Message ID | 1290721502-410-1-git-send-email-albert.aribaud@free.fr |
---|---|
State | Accepted |
Commit | 3336ca60d412b2e1285c0d5e76b7b6f9b4ff19ef |
Headers | show |
Hi Albert, On 11/25/2010 11:45 PM, Albert Aribaud wrote: > bulk addition of ELF relocation support to ARM cpus > arm946es, arm720t,arm920t, arm925t, arm_intcm, ixp, > lh7a40x, s3c44b0, and sa1100. > > Signed-off-by: Albert Aribaud<albert.aribaud@free.fr> > --- > arch/arm/cpu/arm720t/start.S | 119 +++++++++++++++++---------------- > arch/arm/cpu/arm720t/u-boot.lds | 39 +++++++---- > arch/arm/cpu/arm920t/start.S | 125 ++++++++++++++++++----------------- > arch/arm/cpu/arm920t/u-boot.lds | 38 +++++++---- > arch/arm/cpu/arm925t/start.S | 127 +++++++++++++++++++----------------- > arch/arm/cpu/arm925t/u-boot.lds | 38 +++++++---- > arch/arm/cpu/arm946es/start.S | 123 ++++++++++++++++++----------------- > arch/arm/cpu/arm946es/u-boot.lds | 38 +++++++---- > arch/arm/cpu/arm_intcm/start.S | 127 +++++++++++++++++++---------------- > arch/arm/cpu/arm_intcm/u-boot.lds | 38 +++++++---- > arch/arm/cpu/ixp/start.S | 118 +++++++++++++++++---------------- > arch/arm/cpu/ixp/u-boot.lds | 38 +++++++---- > arch/arm/cpu/lh7a40x/start.S | 119 +++++++++++++++++---------------- > arch/arm/cpu/lh7a40x/u-boot.lds | 38 +++++++---- > arch/arm/cpu/s3c44b0/start.S | 131 +++++++++++++++++-------------------- > arch/arm/cpu/s3c44b0/u-boot.lds | 38 +++++++---- > arch/arm/cpu/sa1100/start.S | 119 +++++++++++++++++---------------- > arch/arm/cpu/sa1100/u-boot.lds | 38 +++++++---- > 18 files changed, 785 insertions(+), 666 deletions(-) > how about arm1136 and arm1176? Perhaps they both have relocation code but also they try to use _datarel_* which are not exported by linker anymore. I have my own local patches but I think would be better if you change it together with all other cpus. > diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S > index 8cd267b..46050da 100644 > --- a/arch/arm/cpu/arm720t/start.S > +++ b/arch/arm/cpu/arm720t/start.S > @@ -81,14 +81,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -107,30 +110,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -184,9 +163,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -197,35 +175,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -242,18 +238,25 @@ clbss_l:str r2, [r0] /* clear loop... */ > * We are done. Do not return, instead branch to second part of board > * initialization, now running from RAM. > */ > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > + > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > > /* > ************************************************************************* > diff --git a/arch/arm/cpu/arm720t/u-boot.lds b/arch/arm/cpu/arm720t/u-boot.lds > index 4a0bc70..0686e42 100644 > --- a/arch/arm/cpu/arm720t/u-boot.lds > +++ b/arch/arm/cpu/arm720t/u-boot.lds > @@ -40,29 +40,38 @@ SECTIONS > > . = ALIGN(4); > .data : { > - *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S > index d4edde7..01edb9b 100644 > --- a/arch/arm/cpu/arm920t/start.S > +++ b/arch/arm/cpu/arm920t/start.S > @@ -77,14 +77,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -103,30 +106,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual start code > */ > @@ -230,9 +209,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -243,35 +221,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -289,24 +285,33 @@ clbss_l:str r2, [r0] /* clear loop... */ > * initialization, now running from RAM. > */ > #ifdef CONFIG_NAND_SPL > - ldr pc, _nand_boot > + ldr r0, _nand_boot_ofs > + mov pc, r0 > > -_nand_boot: .word nand_boot > +_nand_boot_ofs: > + .word nand_boot > #else > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > #endif > > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > + > /* > ************************************************************************* > * > diff --git a/arch/arm/cpu/arm920t/u-boot.lds b/arch/arm/cpu/arm920t/u-boot.lds > index 6985434..a6f8b56 100644 > --- a/arch/arm/cpu/arm920t/u-boot.lds > +++ b/arch/arm/cpu/arm920t/u-boot.lds > @@ -49,28 +49,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/arm925t/start.S b/arch/arm/cpu/arm925t/start.S > index 51229c6..ce590a7 100644 > --- a/arch/arm/cpu/arm925t/start.S > +++ b/arch/arm/cpu/arm925t/start.S > @@ -87,14 +87,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -113,30 +116,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -221,9 +200,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -234,35 +212,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -271,6 +267,8 @@ clbss_l:str r2, [r0] /* clear loop... */ > cmp r0, r1 > bne clbss_l > > + bl coloured_LED_init > + bl red_LED_on > #endif > > /* > @@ -278,24 +276,33 @@ clbss_l:str r2, [r0] /* clear loop... */ > * initialization, now running from RAM. > */ > #ifdef CONFIG_NAND_SPL > - ldr pc, _nand_boot > + ldr r0, _nand_boot_ofs > + mov pc, r0 > > -_nand_boot: .word nand_boot > +_nand_boot_ofs: > + .word nand_boot > #else > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > #endif > > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > + > /* > ************************************************************************* > * > diff --git a/arch/arm/cpu/arm925t/u-boot.lds b/arch/arm/cpu/arm925t/u-boot.lds > index 1c4e9bc..7b53edb 100644 > --- a/arch/arm/cpu/arm925t/u-boot.lds > +++ b/arch/arm/cpu/arm925t/u-boot.lds > @@ -44,28 +44,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/arm946es/start.S b/arch/arm/cpu/arm946es/start.S > index cad43ba..f4950f7 100644 > --- a/arch/arm/cpu/arm946es/start.S > +++ b/arch/arm/cpu/arm946es/start.S > @@ -10,6 +10,7 @@ > * Copyright (c) 2002 Gary Jennejohn<garyj@denx.de> > * Copyright (c) 2003 Richard Woodruff<r-woodruff2@ti.com> > * Copyright (c) 2003 Kshitij<kshitij@ti.com> > + * Copyright (c) 2010 Albert Aribaud<albert.aribaud@free.fr> > * > * See file CREDITS for list of people who contributed to this > * project. > @@ -71,6 +72,7 @@ _fiq: > > .balignl 16,0xdeadbeef > > +_vectors_end: > > /* > ************************************************************************* > @@ -91,14 +93,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -117,30 +122,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -190,9 +171,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -203,42 +183,60 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > clbss_l:str r2, [r0] /* clear loop... */ > add r0, r0, #4 > cmp r0, r1 > - bne clbss_l > + blo clbss_l > #endif > > /* > @@ -250,20 +248,27 @@ clbss_l:str r2, [r0] /* clear loop... */ > > _nand_boot: .word nand_boot > #else > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > #endif > > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > + > /* > ************************************************************************* > * > diff --git a/arch/arm/cpu/arm946es/u-boot.lds b/arch/arm/cpu/arm946es/u-boot.lds > index 6535963..eb91979 100644 > --- a/arch/arm/cpu/arm946es/u-boot.lds > +++ b/arch/arm/cpu/arm946es/u-boot.lds > @@ -41,28 +41,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/arm_intcm/start.S b/arch/arm/cpu/arm_intcm/start.S > index 957ca34..fcaba30 100644 > --- a/arch/arm/cpu/arm_intcm/start.S > +++ b/arch/arm/cpu/arm_intcm/start.S > @@ -89,14 +89,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -115,30 +118,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -188,9 +167,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -201,35 +179,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -246,18 +242,33 @@ clbss_l:str r2, [r0] /* clear loop... */ > * We are done. Do not return, instead branch to second part of board > * initialization, now running from RAM. > */ > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > +#ifdef CONFIG_NAND_SPL > + ldr r0, _nand_boot_ofs > + mov pc, r0 > + > +_nand_boot_ofs: > + .word nand_boot > +#else > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > +#endif > + > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > > /* > ************************************************************************* > diff --git a/arch/arm/cpu/arm_intcm/u-boot.lds b/arch/arm/cpu/arm_intcm/u-boot.lds > index 242c7ec..3b5c18d 100644 > --- a/arch/arm/cpu/arm_intcm/u-boot.lds > +++ b/arch/arm/cpu/arm_intcm/u-boot.lds > @@ -41,28 +41,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S > index 8d1aebc..d1ab19b 100644 > --- a/arch/arm/cpu/ixp/start.S > +++ b/arch/arm/cpu/ixp/start.S > @@ -100,14 +100,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -126,30 +129,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -314,9 +293,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -327,35 +305,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -372,19 +368,25 @@ clbss_l:str r2, [r0] /* clear loop... */ > * We are done. Do not return, instead branch to second part of board > * initialization, now running from RAM. > */ > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > > /****************************************************************************/ > /* */ > diff --git a/arch/arm/cpu/ixp/u-boot.lds b/arch/arm/cpu/ixp/u-boot.lds > index f3d9dc5..a55eb8a 100644 > --- a/arch/arm/cpu/ixp/u-boot.lds > +++ b/arch/arm/cpu/ixp/u-boot.lds > @@ -41,28 +41,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/lh7a40x/start.S b/arch/arm/cpu/lh7a40x/start.S > index fd8a40b..5cf477b 100644 > --- a/arch/arm/cpu/lh7a40x/start.S > +++ b/arch/arm/cpu/lh7a40x/start.S > @@ -77,14 +77,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -103,30 +106,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -201,9 +180,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -214,35 +192,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -256,18 +252,25 @@ clbss_l:str r2, [r0] /* clear loop... */ > * We are done. Do not return, instead branch to second part of board > * initialization, now running from RAM. > */ > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > + > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > > /* > ************************************************************************* > diff --git a/arch/arm/cpu/lh7a40x/u-boot.lds b/arch/arm/cpu/lh7a40x/u-boot.lds > index cb55b0a..463237d 100644 > --- a/arch/arm/cpu/lh7a40x/u-boot.lds > +++ b/arch/arm/cpu/lh7a40x/u-boot.lds > @@ -41,28 +41,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/s3c44b0/start.S b/arch/arm/cpu/s3c44b0/start.S > index 67b2c6a..8c7100c 100644 > --- a/arch/arm/cpu/s3c44b0/start.S > +++ b/arch/arm/cpu/s3c44b0/start.S > @@ -68,14 +68,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -94,30 +97,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -173,9 +152,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -186,47 +164,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > -/* > - now copy to sram the interrupt vector > -*/ > - adr r0, real_vectors > - add r2, r0, #1024 > - ldr r1, =0x0c000000 > - add r1, r1, #0x08 > -vector_copy_loop: > - ldmia r0!, {r3-r10} > - stmia r1!, {r3-r10} > - cmp r0, r2 > - blo vector_copy_loop > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -243,18 +227,25 @@ clbss_l:str r2, [r0] /* clear loop... */ > * We are done. Do not return, instead branch to second part of board > * initialization, now running from RAM. > */ > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > + > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > > /* > ************************************************************************* > diff --git a/arch/arm/cpu/s3c44b0/u-boot.lds b/arch/arm/cpu/s3c44b0/u-boot.lds > index bbc8c3a..ac29440 100644 > --- a/arch/arm/cpu/s3c44b0/u-boot.lds > +++ b/arch/arm/cpu/s3c44b0/u-boot.lds > @@ -41,28 +41,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > } > diff --git a/arch/arm/cpu/sa1100/start.S b/arch/arm/cpu/sa1100/start.S > index ace0c07..36d44da 100644 > --- a/arch/arm/cpu/sa1100/start.S > +++ b/arch/arm/cpu/sa1100/start.S > @@ -78,14 +78,17 @@ _TEXT_BASE: > > /* > * These are defined in the board-specific linker script. > + * Subtracting _start from them lets the linker put their > + * relative position in the executable instead of leaving > + * them null. > */ > -.globl _bss_start > -_bss_start: > - .word __bss_start > +.globl _bss_start_ofs > +_bss_start_ofs: > + .word __bss_start - _start > > -.globl _bss_end > -_bss_end: > - .word _end > +.globl _bss_end_ofs > +_bss_end_ofs: > + .word _end - _start > > #ifdef CONFIG_USE_IRQ > /* IRQ stack memory (calculated at run-time) */ > @@ -104,30 +107,6 @@ FIQ_STACK_START: > IRQ_STACK_START_IN: > .word 0x0badc0de > > -.globl _datarel_start > -_datarel_start: > - .word __datarel_start > - > -.globl _datarelrolocal_start > -_datarelrolocal_start: > - .word __datarelrolocal_start > - > -.globl _datarellocal_start > -_datarellocal_start: > - .word __datarellocal_start > - > -.globl _datarelro_start > -_datarelro_start: > - .word __datarelro_start > - > -.globl _got_start > -_got_start: > - .word __got_start > - > -.globl _got_end > -_got_end: > - .word __got_end > - > /* > * the actual reset code > */ > @@ -177,9 +156,8 @@ stack_setup: > > adr r0, _start > ldr r2, _TEXT_BASE > - ldr r3, _bss_start > - sub r2, r3, r2 /* r2<- size of armboot */ > - add r2, r0, r2 /* r2<- source end address */ > + ldr r3, _bss_start_ofs > + add r2, r0, r3 /* r2<- source end address */ > cmp r0, r6 > beq clear_bss > > @@ -190,35 +168,53 @@ copy_loop: > blo copy_loop > > #ifndef CONFIG_PRELOADER > - /* fix got entries */ > - ldr r1, _TEXT_BASE /* Text base */ > - mov r0, r7 /* reloc addr */ > - ldr r2, _got_start /* addr in Flash */ > - ldr r3, _got_end /* addr in Flash */ > - sub r3, r3, r1 > - add r3, r3, r0 > - sub r2, r2, r1 > - add r2, r2, r0 > - > + /* > + * fix .rel.dyn relocations > + */ > + ldr r0, _TEXT_BASE /* r0<- Text base */ > + sub r9, r7, r0 /* r9<- relocation offset */ > + ldr r10, _dynsym_start_ofs /* r10<- sym table ofs */ > + add r10, r10, r0 /* r10<- sym table in FLASH */ > + ldr r2, _rel_dyn_start_ofs /* r2<- rel dyn start ofs */ > + add r2, r2, r0 /* r2<- rel dyn start in FLASH */ > + ldr r3, _rel_dyn_end_ofs /* r3<- rel dyn end ofs */ > + add r3, r3, r0 /* r3<- rel dyn end in FLASH */ > fixloop: > - ldr r4, [r2] > - sub r4, r4, r1 > - add r4, r4, r0 > - str r4, [r2] > - add r2, r2, #4 > + ldr r0, [r2] /* r0<- location to fix up, IN FLASH! */ > + add r0, r0, r9 /* r0<- location to fix up in RAM */ > + ldr r1, [r2, #4] > + and r8, r1, #0xff > + cmp r8, #23 /* relative fixup? */ > + beq fixrel > + cmp r8, #2 /* absolute fixup? */ > + beq fixabs > + /* ignore unknown type of fixup */ > + b fixnext > +fixabs: > + /* absolute fix: set location to (offset) symbol value */ > + mov r1, r1, LSR #4 /* r1<- symbol index in .dynsym */ > + add r1, r10, r1 /* r1<- address of symbol in table */ > + ldr r1, [r1, #4] /* r1<- symbol value */ > + add r1, r9 /* r1<- relocated sym addr */ > + b fixnext > +fixrel: > + /* relative fix: increase location by offset */ > + ldr r1, [r0] > + add r1, r1, r9 > +fixnext: > + str r1, [r0] > + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ > cmp r2, r3 > blo fixloop > #endif > > clear_bss: > #ifndef CONFIG_PRELOADER > - ldr r0, _bss_start > - ldr r1, _bss_end > + ldr r0, _bss_start_ofs > + ldr r1, _bss_end_ofs > ldr r3, _TEXT_BASE /* Text base */ > mov r4, r7 /* reloc addr */ > - sub r0, r0, r3 > add r0, r0, r4 > - sub r1, r1, r3 > add r1, r1, r4 > mov r2, #0x00000000 /* clear */ > > @@ -232,18 +228,25 @@ clbss_l:str r2, [r0] /* clear loop... */ > * We are done. Do not return, instead branch to second part of board > * initialization, now running from RAM. > */ > - ldr r0, _TEXT_BASE > - ldr r2, _board_init_r > - sub r2, r2, r0 > - add r2, r2, r7 /* position from board_init_r in RAM */ > + ldr r0, _board_init_r_ofs > + adr r1, _start > + add lr, r0, r1 > + add lr, lr, r9 > /* setup parameters for board_init_r */ > mov r0, r5 /* gd_t */ > mov r1, r7 /* dest_addr */ > /* jump to it ... */ > - mov lr, r2 > mov pc, lr > > -_board_init_r: .word board_init_r > +_board_init_r_ofs: > + .word board_init_r - _start > + > +_rel_dyn_start_ofs: > + .word __rel_dyn_start - _start > +_rel_dyn_end_ofs: > + .word __rel_dyn_end - _start > +_dynsym_start_ofs: > + .word __dynsym_start - _start > > /* > ************************************************************************* > diff --git a/arch/arm/cpu/sa1100/u-boot.lds b/arch/arm/cpu/sa1100/u-boot.lds > index 2e29291..fa6d05c 100644 > --- a/arch/arm/cpu/sa1100/u-boot.lds > +++ b/arch/arm/cpu/sa1100/u-boot.lds > @@ -44,28 +44,38 @@ SECTIONS > . = ALIGN(4); > .data : { > *(.data) > - __datarel_start = .; > - *(.data.rel) > - __datarelrolocal_start = .; > - *(.data.rel.ro.local) > - __datarellocal_start = .; > - *(.data.rel.local) > - __datarelro_start = .; > - *(.data.rel.ro) > } > > - __got_start = .; > . = ALIGN(4); > - .got : { *(.got) } > > - __got_end = .; > . = .; > __u_boot_cmd_start = .; > .u_boot_cmd : { *(.u_boot_cmd) } > __u_boot_cmd_end = .; > > . = ALIGN(4); > - __bss_start = .; > - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } > - _end = .; > + > + .rel.dyn : { > + __rel_dyn_start = .; > + *(.rel*) > + __rel_dyn_end = .; > + } > + > + .dynsym : { > + __dynsym_start = .; > + *(.dynsym) > + } > + > + .bss __rel_dyn_start (OVERLAY) : { > + __bss_start = .; > + *(.bss) > + . = ALIGN(4); > + _end = .; > + } > + > + /DISCARD/ : { *(.dynstr*) } > + /DISCARD/ : { *(.dynamic*) } > + /DISCARD/ : { *(.plt*) } > + /DISCARD/ : { *(.interp*) } > + /DISCARD/ : { *(.gnu*) } > }
Hi Darius, Le 26/11/2010 19:04, Darius Augulis a écrit : > Hi Albert, > how about arm1136 and arm1176? Perhaps they both have relocation code > but also they try to use _datarel_* which are not exported by linker > anymore. If I am not mistaken, arm1136 and arm1176 are dealt with in v5 of my patch <http://article.gmane.org/gmane.comp.boot-loaders.u-boot/88966>, which is already applied to u-boot-arm and will thus be pulled into u-boot soon. > I have my own local patches but I think would be better if you change it > together with all other cpus. Please verify my V5 patch and, if your patches are needed above it, please post them here to be apllied above mine. Amicalement,
Hi, On 11/26/2010 08:12 PM, Albert ARIBAUD wrote: > Hi Darius, > > Le 26/11/2010 19:04, Darius Augulis a écrit : > >> Hi Albert, > >> how about arm1136 and arm1176? Perhaps they both have relocation code >> but also they try to use _datarel_* which are not exported by linker >> anymore. > > If I am not mistaken, arm1136 and arm1176 are dealt with in v5 of my > patch<http://article.gmane.org/gmane.comp.boot-loaders.u-boot/88966>, > which is already applied to u-boot-arm and will thus be pulled into > u-boot soon. as I can see only u-boot.lds is changed for arm1176 and start.S isn't. arm1136 got changed both these files. > >> I have my own local patches but I think would be better if you change it >> together with all other cpus. > > Please verify my V5 patch and, if your patches are needed above it, > please post them here to be apllied above mine. they are very raw and not ready yet. Not sure when will have time to finish it. Darius. > > Amicalement,
Le 26/11/2010 19:18, Darius Augulis a écrit : > Hi, > > On 11/26/2010 08:12 PM, Albert ARIBAUD wrote: >> Hi Darius, >> >> Le 26/11/2010 19:04, Darius Augulis a écrit : >> >>> Hi Albert, >> >>> how about arm1136 and arm1176? Perhaps they both have relocation code >>> but also they try to use _datarel_* which are not exported by linker >>> anymore. >> >> If I am not mistaken, arm1136 and arm1176 are dealt with in v5 of my >> patch<http://article.gmane.org/gmane.comp.boot-loaders.u-boot/88966>, >> which is already applied to u-boot-arm and will thus be pulled into >> u-boot soon. > > as I can see only u-boot.lds is changed for arm1176 and start.S isn't. > arm1136 got changed both these files. Correct, the arm1176 start.S is only half-fixed for ELF relocations. I'll post a bugfix right away. >>> I have my own local patches but I think would be better if you change it >>> together with all other cpus. >> >> Please verify my V5 patch and, if your patches are needed above it, >> please post them here to be apllied above mine. > > they are very raw and not ready yet. Not sure when will have time to > finish it. What do they add beside the fix to arm1136/1176 ? Amicalement,
On 11/26/2010 08:34 PM, Albert ARIBAUD wrote: > Le 26/11/2010 19:18, Darius Augulis a écrit : >> Hi, >> >> On 11/26/2010 08:12 PM, Albert ARIBAUD wrote: >>> Hi Darius, >>> >>> Le 26/11/2010 19:04, Darius Augulis a écrit : >>> >>>> Hi Albert, >>> >>>> how about arm1136 and arm1176? Perhaps they both have relocation code >>>> but also they try to use _datarel_* which are not exported by linker >>>> anymore. >>> >>> If I am not mistaken, arm1136 and arm1176 are dealt with in v5 of my >>> patch<http://article.gmane.org/gmane.comp.boot-loaders.u-boot/88966>, >>> which is already applied to u-boot-arm and will thus be pulled into >>> u-boot soon. >> >> as I can see only u-boot.lds is changed for arm1176 and start.S isn't. >> arm1136 got changed both these files. > > Correct, the arm1176 start.S is only half-fixed for ELF relocations. > I'll post a bugfix right away. > >>>> I have my own local patches but I think would be better if you >>>> change it >>>> together with all other cpus. >>> >>> Please verify my V5 patch and, if your patches are needed above it, >>> please post them here to be apllied above mine. >> >> they are very raw and not ready yet. Not sure when will have time to >> finish it. > > What do they add beside the fix to arm1136/1176 ? actually it's not a separate patch but merged into other big patch which adds support for mini6410 board. I will resolve my local conflicts after pulling your bugfix. Darius. > > Amicalement,
Dear Albert Aribaud, In message <1290721502-410-1-git-send-email-albert.aribaud@free.fr> you wrote: > bulk addition of ELF relocation support to ARM cpus > arm946es, arm720t,arm920t, arm925t, arm_intcm, ixp, > lh7a40x, s3c44b0, and sa1100. > > Signed-off-by: Albert Aribaud <albert.aribaud@free.fr> > --- > arch/arm/cpu/arm720t/start.S | 119 +++++++++++++++++---------------- > arch/arm/cpu/arm720t/u-boot.lds | 39 +++++++---- > arch/arm/cpu/arm920t/start.S | 125 ++++++++++++++++++----------------- > arch/arm/cpu/arm920t/u-boot.lds | 38 +++++++---- > arch/arm/cpu/arm925t/start.S | 127 +++++++++++++++++++----------------- > arch/arm/cpu/arm925t/u-boot.lds | 38 +++++++---- > arch/arm/cpu/arm946es/start.S | 123 ++++++++++++++++++----------------- > arch/arm/cpu/arm946es/u-boot.lds | 38 +++++++---- > arch/arm/cpu/arm_intcm/start.S | 127 +++++++++++++++++++---------------- > arch/arm/cpu/arm_intcm/u-boot.lds | 38 +++++++---- > arch/arm/cpu/ixp/start.S | 118 +++++++++++++++++---------------- > arch/arm/cpu/ixp/u-boot.lds | 38 +++++++---- > arch/arm/cpu/lh7a40x/start.S | 119 +++++++++++++++++---------------- > arch/arm/cpu/lh7a40x/u-boot.lds | 38 +++++++---- > arch/arm/cpu/s3c44b0/start.S | 131 +++++++++++++++++-------------------- > arch/arm/cpu/s3c44b0/u-boot.lds | 38 +++++++---- > arch/arm/cpu/sa1100/start.S | 119 +++++++++++++++++---------------- > arch/arm/cpu/sa1100/u-boot.lds | 38 +++++++---- > 18 files changed, 785 insertions(+), 666 deletions(-) Applied, thanks. Best regards, Wolfgang Denk
diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index 8cd267b..46050da 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -81,14 +81,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -107,30 +110,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -184,9 +163,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -197,35 +175,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -242,18 +238,25 @@ clbss_l:str r2, [r0] /* clear loop... */ * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start /* ************************************************************************* diff --git a/arch/arm/cpu/arm720t/u-boot.lds b/arch/arm/cpu/arm720t/u-boot.lds index 4a0bc70..0686e42 100644 --- a/arch/arm/cpu/arm720t/u-boot.lds +++ b/arch/arm/cpu/arm720t/u-boot.lds @@ -40,29 +40,38 @@ SECTIONS . = ALIGN(4); .data : { - *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S index d4edde7..01edb9b 100644 --- a/arch/arm/cpu/arm920t/start.S +++ b/arch/arm/cpu/arm920t/start.S @@ -77,14 +77,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -103,30 +106,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual start code */ @@ -230,9 +209,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -243,35 +221,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -289,24 +285,33 @@ clbss_l:str r2, [r0] /* clear loop... */ * initialization, now running from RAM. */ #ifdef CONFIG_NAND_SPL - ldr pc, _nand_boot + ldr r0, _nand_boot_ofs + mov pc, r0 -_nand_boot: .word nand_boot +_nand_boot_ofs: + .word nand_boot #else - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start #endif +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start + /* ************************************************************************* * diff --git a/arch/arm/cpu/arm920t/u-boot.lds b/arch/arm/cpu/arm920t/u-boot.lds index 6985434..a6f8b56 100644 --- a/arch/arm/cpu/arm920t/u-boot.lds +++ b/arch/arm/cpu/arm920t/u-boot.lds @@ -49,28 +49,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/arm925t/start.S b/arch/arm/cpu/arm925t/start.S index 51229c6..ce590a7 100644 --- a/arch/arm/cpu/arm925t/start.S +++ b/arch/arm/cpu/arm925t/start.S @@ -87,14 +87,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -113,30 +116,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -221,9 +200,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -234,35 +212,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -271,6 +267,8 @@ clbss_l:str r2, [r0] /* clear loop... */ cmp r0, r1 bne clbss_l + bl coloured_LED_init + bl red_LED_on #endif /* @@ -278,24 +276,33 @@ clbss_l:str r2, [r0] /* clear loop... */ * initialization, now running from RAM. */ #ifdef CONFIG_NAND_SPL - ldr pc, _nand_boot + ldr r0, _nand_boot_ofs + mov pc, r0 -_nand_boot: .word nand_boot +_nand_boot_ofs: + .word nand_boot #else - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start #endif +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start + /* ************************************************************************* * diff --git a/arch/arm/cpu/arm925t/u-boot.lds b/arch/arm/cpu/arm925t/u-boot.lds index 1c4e9bc..7b53edb 100644 --- a/arch/arm/cpu/arm925t/u-boot.lds +++ b/arch/arm/cpu/arm925t/u-boot.lds @@ -44,28 +44,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/arm946es/start.S b/arch/arm/cpu/arm946es/start.S index cad43ba..f4950f7 100644 --- a/arch/arm/cpu/arm946es/start.S +++ b/arch/arm/cpu/arm946es/start.S @@ -10,6 +10,7 @@ * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2010 Albert Aribaud <albert.aribaud@free.fr> * * See file CREDITS for list of people who contributed to this * project. @@ -71,6 +72,7 @@ _fiq: .balignl 16,0xdeadbeef +_vectors_end: /* ************************************************************************* @@ -91,14 +93,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -117,30 +122,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -190,9 +171,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -203,42 +183,60 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ clbss_l:str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 - bne clbss_l + blo clbss_l #endif /* @@ -250,20 +248,27 @@ clbss_l:str r2, [r0] /* clear loop... */ _nand_boot: .word nand_boot #else - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start #endif +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start + /* ************************************************************************* * diff --git a/arch/arm/cpu/arm946es/u-boot.lds b/arch/arm/cpu/arm946es/u-boot.lds index 6535963..eb91979 100644 --- a/arch/arm/cpu/arm946es/u-boot.lds +++ b/arch/arm/cpu/arm946es/u-boot.lds @@ -41,28 +41,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/arm_intcm/start.S b/arch/arm/cpu/arm_intcm/start.S index 957ca34..fcaba30 100644 --- a/arch/arm/cpu/arm_intcm/start.S +++ b/arch/arm/cpu/arm_intcm/start.S @@ -89,14 +89,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -115,30 +118,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -188,9 +167,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -201,35 +179,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -246,18 +242,33 @@ clbss_l:str r2, [r0] /* clear loop... */ * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ +#ifdef CONFIG_NAND_SPL + ldr r0, _nand_boot_ofs + mov pc, r0 + +_nand_boot_ofs: + .word nand_boot +#else + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start +#endif + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start /* ************************************************************************* diff --git a/arch/arm/cpu/arm_intcm/u-boot.lds b/arch/arm/cpu/arm_intcm/u-boot.lds index 242c7ec..3b5c18d 100644 --- a/arch/arm/cpu/arm_intcm/u-boot.lds +++ b/arch/arm/cpu/arm_intcm/u-boot.lds @@ -41,28 +41,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S index 8d1aebc..d1ab19b 100644 --- a/arch/arm/cpu/ixp/start.S +++ b/arch/arm/cpu/ixp/start.S @@ -100,14 +100,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -126,30 +129,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -314,9 +293,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -327,35 +305,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -372,19 +368,25 @@ clbss_l:str r2, [r0] /* clear loop... */ * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start /****************************************************************************/ /* */ diff --git a/arch/arm/cpu/ixp/u-boot.lds b/arch/arm/cpu/ixp/u-boot.lds index f3d9dc5..a55eb8a 100644 --- a/arch/arm/cpu/ixp/u-boot.lds +++ b/arch/arm/cpu/ixp/u-boot.lds @@ -41,28 +41,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/lh7a40x/start.S b/arch/arm/cpu/lh7a40x/start.S index fd8a40b..5cf477b 100644 --- a/arch/arm/cpu/lh7a40x/start.S +++ b/arch/arm/cpu/lh7a40x/start.S @@ -77,14 +77,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -103,30 +106,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -201,9 +180,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -214,35 +192,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -256,18 +252,25 @@ clbss_l:str r2, [r0] /* clear loop... */ * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start /* ************************************************************************* diff --git a/arch/arm/cpu/lh7a40x/u-boot.lds b/arch/arm/cpu/lh7a40x/u-boot.lds index cb55b0a..463237d 100644 --- a/arch/arm/cpu/lh7a40x/u-boot.lds +++ b/arch/arm/cpu/lh7a40x/u-boot.lds @@ -41,28 +41,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/s3c44b0/start.S b/arch/arm/cpu/s3c44b0/start.S index 67b2c6a..8c7100c 100644 --- a/arch/arm/cpu/s3c44b0/start.S +++ b/arch/arm/cpu/s3c44b0/start.S @@ -68,14 +68,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -94,30 +97,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -173,9 +152,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -186,47 +164,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif -/* - now copy to sram the interrupt vector -*/ - adr r0, real_vectors - add r2, r0, #1024 - ldr r1, =0x0c000000 - add r1, r1, #0x08 -vector_copy_loop: - ldmia r0!, {r3-r10} - stmia r1!, {r3-r10} - cmp r0, r2 - blo vector_copy_loop clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -243,18 +227,25 @@ clbss_l:str r2, [r0] /* clear loop... */ * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start /* ************************************************************************* diff --git a/arch/arm/cpu/s3c44b0/u-boot.lds b/arch/arm/cpu/s3c44b0/u-boot.lds index bbc8c3a..ac29440 100644 --- a/arch/arm/cpu/s3c44b0/u-boot.lds +++ b/arch/arm/cpu/s3c44b0/u-boot.lds @@ -41,28 +41,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } } diff --git a/arch/arm/cpu/sa1100/start.S b/arch/arm/cpu/sa1100/start.S index ace0c07..36d44da 100644 --- a/arch/arm/cpu/sa1100/start.S +++ b/arch/arm/cpu/sa1100/start.S @@ -78,14 +78,17 @@ _TEXT_BASE: /* * These are defined in the board-specific linker script. + * Subtracting _start from them lets the linker put their + * relative position in the executable instead of leaving + * them null. */ -.globl _bss_start -_bss_start: - .word __bss_start +.globl _bss_start_ofs +_bss_start_ofs: + .word __bss_start - _start -.globl _bss_end -_bss_end: - .word _end +.globl _bss_end_ofs +_bss_end_ofs: + .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ @@ -104,30 +107,6 @@ FIQ_STACK_START: IRQ_STACK_START_IN: .word 0x0badc0de -.globl _datarel_start -_datarel_start: - .word __datarel_start - -.globl _datarelrolocal_start -_datarelrolocal_start: - .word __datarelrolocal_start - -.globl _datarellocal_start -_datarellocal_start: - .word __datarellocal_start - -.globl _datarelro_start -_datarelro_start: - .word __datarelro_start - -.globl _got_start -_got_start: - .word __got_start - -.globl _got_end -_got_end: - .word __got_end - /* * the actual reset code */ @@ -177,9 +156,8 @@ stack_setup: adr r0, _start ldr r2, _TEXT_BASE - ldr r3, _bss_start - sub r2, r3, r2 /* r2 <- size of armboot */ - add r2, r0, r2 /* r2 <- source end address */ + ldr r3, _bss_start_ofs + add r2, r0, r3 /* r2 <- source end address */ cmp r0, r6 beq clear_bss @@ -190,35 +168,53 @@ copy_loop: blo copy_loop #ifndef CONFIG_PRELOADER - /* fix got entries */ - ldr r1, _TEXT_BASE /* Text base */ - mov r0, r7 /* reloc addr */ - ldr r2, _got_start /* addr in Flash */ - ldr r3, _got_end /* addr in Flash */ - sub r3, r3, r1 - add r3, r3, r0 - sub r2, r2, r1 - add r2, r2, r0 - + /* + * fix .rel.dyn relocations + */ + ldr r0, _TEXT_BASE /* r0 <- Text base */ + sub r9, r7, r0 /* r9 <- relocation offset */ + ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ + add r10, r10, r0 /* r10 <- sym table in FLASH */ + ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ + add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ + ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ + add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ fixloop: - ldr r4, [r2] - sub r4, r4, r1 - add r4, r4, r0 - str r4, [r2] - add r2, r2, #4 + ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ + add r0, r0, r9 /* r0 <- location to fix up in RAM */ + ldr r1, [r2, #4] + and r8, r1, #0xff + cmp r8, #23 /* relative fixup? */ + beq fixrel + cmp r8, #2 /* absolute fixup? */ + beq fixabs + /* ignore unknown type of fixup */ + b fixnext +fixabs: + /* absolute fix: set location to (offset) symbol value */ + mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ + add r1, r10, r1 /* r1 <- address of symbol in table */ + ldr r1, [r1, #4] /* r1 <- symbol value */ + add r1, r9 /* r1 <- relocated sym addr */ + b fixnext +fixrel: + /* relative fix: increase location by offset */ + ldr r1, [r0] + add r1, r1, r9 +fixnext: + str r1, [r0] + add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ cmp r2, r3 blo fixloop #endif clear_bss: #ifndef CONFIG_PRELOADER - ldr r0, _bss_start - ldr r1, _bss_end + ldr r0, _bss_start_ofs + ldr r1, _bss_end_ofs ldr r3, _TEXT_BASE /* Text base */ mov r4, r7 /* reloc addr */ - sub r0, r0, r3 add r0, r0, r4 - sub r1, r1, r3 add r1, r1, r4 mov r2, #0x00000000 /* clear */ @@ -232,18 +228,25 @@ clbss_l:str r2, [r0] /* clear loop... */ * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - ldr r0, _TEXT_BASE - ldr r2, _board_init_r - sub r2, r2, r0 - add r2, r2, r7 /* position from board_init_r in RAM */ + ldr r0, _board_init_r_ofs + adr r1, _start + add lr, r0, r1 + add lr, lr, r9 /* setup parameters for board_init_r */ mov r0, r5 /* gd_t */ mov r1, r7 /* dest_addr */ /* jump to it ... */ - mov lr, r2 mov pc, lr -_board_init_r: .word board_init_r +_board_init_r_ofs: + .word board_init_r - _start + +_rel_dyn_start_ofs: + .word __rel_dyn_start - _start +_rel_dyn_end_ofs: + .word __rel_dyn_end - _start +_dynsym_start_ofs: + .word __dynsym_start - _start /* ************************************************************************* diff --git a/arch/arm/cpu/sa1100/u-boot.lds b/arch/arm/cpu/sa1100/u-boot.lds index 2e29291..fa6d05c 100644 --- a/arch/arm/cpu/sa1100/u-boot.lds +++ b/arch/arm/cpu/sa1100/u-boot.lds @@ -44,28 +44,38 @@ SECTIONS . = ALIGN(4); .data : { *(.data) - __datarel_start = .; - *(.data.rel) - __datarelrolocal_start = .; - *(.data.rel.ro.local) - __datarellocal_start = .; - *(.data.rel.local) - __datarelro_start = .; - *(.data.rel.ro) } - __got_start = .; . = ALIGN(4); - .got : { *(.got) } - __got_end = .; . = .; __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .; . = ALIGN(4); - __bss_start = .; - .bss (NOLOAD) : { *(.bss) . = ALIGN(4); } - _end = .; + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .dynsym : { + __dynsym_start = .; + *(.dynsym) + } + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + . = ALIGN(4); + _end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } }
bulk addition of ELF relocation support to ARM cpus arm946es, arm720t,arm920t, arm925t, arm_intcm, ixp, lh7a40x, s3c44b0, and sa1100. Signed-off-by: Albert Aribaud <albert.aribaud@free.fr> --- arch/arm/cpu/arm720t/start.S | 119 +++++++++++++++++---------------- arch/arm/cpu/arm720t/u-boot.lds | 39 +++++++---- arch/arm/cpu/arm920t/start.S | 125 ++++++++++++++++++----------------- arch/arm/cpu/arm920t/u-boot.lds | 38 +++++++---- arch/arm/cpu/arm925t/start.S | 127 +++++++++++++++++++----------------- arch/arm/cpu/arm925t/u-boot.lds | 38 +++++++---- arch/arm/cpu/arm946es/start.S | 123 ++++++++++++++++++----------------- arch/arm/cpu/arm946es/u-boot.lds | 38 +++++++---- arch/arm/cpu/arm_intcm/start.S | 127 +++++++++++++++++++---------------- arch/arm/cpu/arm_intcm/u-boot.lds | 38 +++++++---- arch/arm/cpu/ixp/start.S | 118 +++++++++++++++++---------------- arch/arm/cpu/ixp/u-boot.lds | 38 +++++++---- arch/arm/cpu/lh7a40x/start.S | 119 +++++++++++++++++---------------- arch/arm/cpu/lh7a40x/u-boot.lds | 38 +++++++---- arch/arm/cpu/s3c44b0/start.S | 131 +++++++++++++++++-------------------- arch/arm/cpu/s3c44b0/u-boot.lds | 38 +++++++---- arch/arm/cpu/sa1100/start.S | 119 +++++++++++++++++---------------- arch/arm/cpu/sa1100/u-boot.lds | 38 +++++++---- 18 files changed, 785 insertions(+), 666 deletions(-)