[U-Boot] [PATCH 2/2] [NEXT] arm926ejs: reduce code size with -msingle-pic-base

Ben Gardiner
2010-09-22T20:51:31Z

On Wed, Sep 22, 2010 at 3:07 PM, Albert ARIBAUD <albert.aribaud@free.fr> wrote:
> Basically your test seems to demonstrate show that the pic base value
> computed in start.S does not work for board_init_f.
>
> Did you execute the binary at the address specified in TEXT_BASE? If not,
> please adjust TEXT_BASE to the location where u-boot resides when you debug
> it.

On boot we see printed
"Jumping to entry point at 0xC1080000."
by UBL.

The debugger agrees:
(gdb) info registers
r0 0x2710 10000
r1 0x0 0
r2 0x80003478 2147497080
r3 0xc1080000 3238526976
r4 0x80003484 2147497092
r5 0x80003480 2147497088
r6 0xc7fe9760 3355350880
r7 0xc7fbd000 3355168768
r8 0xc7ea8f8c 3354038156
r9 0xa1892306 2710119174
r10 0xa1892306 2710119174
r11 0xc7ea8f84 3354038148
r12 0x30 48
sp 0x800037d0 0x800037d0
lr 0x80000120 2147483936
pc 0xc1080000 0xc1080000 <_start>
fps 0x0 0
cpsr 0x600000d3 1610612947
(gdb) l
50 */
51
52
53 .globl _start
54 _start:
55 b reset
56 #ifdef CONFIG_PRELOADER
57 /* No exception handlers in preloader */
58 ldr pc, _hang
59 ldr pc, _hang
(gdb)

It appears that TEXT_BASE Is 0xc1080040 in the binary though it is
specified as 0xc1080000:
$arm-none-linux-gnueabi-nm u-boot |grep TEXT
c1080040 T _TEXT_BASE
$cat board/davinci/da8xxevm/config.mk |grep TEXT
TEXT_BASE = 0xC1080000

but I guess that's OK since _TEXT_BASE is a label at start.S:118 ...

I'm not sure if it is relevant but note that the da850 is a board for
which we have "#undef CONFIG_SKIP_RELOCATE_UBOOT"

> Otherwise, can you do the following? This will help me see if the pic base
> computed in start.S is the same as the one computed by each function without
> -msingle-pic-base.
>
> 1) build with your fix in;
>
> 2) debug (at the assembly instruction level) the start.S code and see what
> value ends up in r10 (aka sl) right before calling board_init_f;

(gdb) info registers
r0 0x0 0
r1 0x0 0
r2 0x80003478 2147497080
r3 0xc1080000 3238526976
r4 0x80003484 2147497092
r5 0x80003480 2147497088
r6 0xc7fe9ba0 3355351968
r7 0xc7fbb000 3355160576
r8 0xc7ea6f8c 3354029964
r9 0xc10ae600 3238716928
r10 0xc10ae600 3238716928
r11 0xc7ea6d3c 3354029372
r12 0x30 48
sp 0xc0000f80 0xc0000f80
lr 0x80000120 2147483936
pc 0xc1080088 0xc1080088 <reset+32>
fps 0x0 0
cpsr 0x600000d3 1610612947
(gdb)

> 3) proceed (still at the assembly instruction level) until you get within
> board_init_f. Among the first instructions will be the recomputation of
> 10/sl; see what value it is assigned;

I couldn't see any modification of r10 in board_init_f; what follows
is the assembly of the first instructions of that function:
c1080730 <board_init_f>:
c1080730: e92d4800 push {fp, lr}
c1080734: e28db004 add fp, sp, #4 ; 0x4
c1080738: e24dd020 sub sp, sp, #32 ; 0x20
c108073c: e59f21e8 ldr r2, [pc, #488] ; c108092c
<board_init_f+0x1fc>
c1080740: e50b2024 str r2, [fp, #-36]
c1080744: e51b3024 ldr r3, [fp, #-36]
c1080748: e08f3003 add r3, pc, r3
c108074c: e50b3024 str r3, [fp, #-36]
c1080750: e50b0020 str r0, [fp, #-32]
c1080754: e59f81d4 ldr r8, [pc, #468] ; c1080930
<board_init_f+0x200>
c1080758: e1a03008 mov r3, r8
c108075c: e1a00003 mov r0, r3
c1080760: e3a01000 mov r1, #0 ; 0x0
c1080764: e3a0205c mov r2, #92 ; 0x5c
c1080768: eb007a1c bl c109efe0 <memset>
c108076c: e1a01008 mov r1, r8
c1080770: e59f31bc ldr r3, [pc, #444] ; c1080934
<board_init_f+0x204>
c1080774: e51b0024 ldr r0, [fp, #-36]
c1080778: e7903003 ldr r3, [r0, r3]
c108077c: e5932000 ldr r2, [r3]
c1080780: e59f31b0 ldr r3, [pc, #432] ; c1080938
<board_init_f+0x208>
c1080784: e51b0024 ldr r0, [fp, #-36]
c1080788: e7903003 ldr r3, [r0, r3]
c108078c: e5933000 ldr r3, [r3]
c1080790: e0633002 rsb r3, r3, r2
c1080794: e5813024 str r3, [r1, #36]
c1080798: e59f319c ldr r3, [pc, #412] ; c108093c
<board_init_f+0x20c>
c108079c: e51b2024 ldr r2, [fp, #-36]
c10807a0: e0823003 add r3, r2, r3
c10807a4: e50b3014 str r3, [fp, #-20]
c10807a8: ea000009 b c10807d4 <board_init_f+0xa4>
c10807ac: e51b3014 ldr r3, [fp, #-20]
c10807b0: e5933000 ldr r3, [r3]
c10807b4: e12fff33 blx r3
c10807b8: e1a03000 mov r3, r0
c10807bc: e3530000 cmp r3, #0 ; 0x0
c10807c0: 0a000000 beq c10807c8 <board_init_f+0x98>
c10807c4: eb0000d3 bl c1080b18 <hang>
c10807c8: e51b3014 ldr r3, [fp, #-20]
c10807cc: e2833004 add r3, r3, #4 ; 0x4
c10807d0: e50b3014 str r3, [fp, #-20]
c10807d4: e51b3014 ldr r3, [fp, #-20]
c10807d8: e5933000 ldr r3, [r3]
c10807dc: e3530000 cmp r3, #0 ; 0x0
c10807e0: 1afffff1 bne c10807ac <board_init_f+0x7c>
c10807e4: e1a03008 mov r3, r8
c10807e8: e5933020 ldr r3, [r3, #32]
c10807ec: e2833103 add r3, r3, #-1073741824 ; 0xc0000000
c10807f0: e50b300c str r3, [fp, #-12]
c10807f4: e51b300c ldr r3, [fp, #-12]
c10807f8: e2433901 sub r3, r3, #16384 ; 0x4000
c10807fc: e50b300c str r3, [fp, #-12]
c1080800: e51b300c ldr r3, [fp, #-12]
c1080804: e1a03823 lsr r3, r3, #16
c1080808: e1a03803 lsl r3, r3, #16
c108080c: e50b300c str r3, [fp, #-12]
c1080810: e1a02008 mov r2, r8
c1080814: e51b300c ldr r3, [fp, #-12]
c1080818: e5823034 str r3, [r2, #52]
c108081c: e51b300c ldr r3, [fp, #-12]
c1080820: e3c33eff bic r3, r3, #4080 ; 0xff0
c1080824: e3c3300f bic r3, r3, #15 ; 0xf

just before board_init_f calls relocate_code the registers are as follows:
(gdb) info registers
r0 0xc7ea6f8c 3354029964
r1 0xc0000f80 3221229440
r2 0x0 0
r3 0xc7ea6f8c 3354029964
r4 0x80003484 2147497092
r5 0x80003480 2147497088
r6 0xc7fe9ba0 3355351968
r7 0xc7fbb000 3355160576
r8 0xc0000f80 3221229440
r9 0xc10ae600 3238716928
r10 0xc10ae600 3238716928
r11 0xc0000f7c 3221229436
r12 0xc10ae600 3238716928
sp 0xc0000f58 0xc0000f58
lr 0xc108091c 3238529308
pc 0xc108091c 0xc108091c <board_init_f+492>
fps 0x0 0
cpsr 0x600000d3 1610612947

> 4) compare values found in 2 and 3 with the value of __got_base in the .map
> file.

In 2 and 3 r10 was 0xc10ae600; the System.map shows:
$cat System.map |grep got_base
c1080150 t relocate_got_base_r
c108017c t _got_base
c1080180 t _relocate_got_base_r
c10ae600 A __got_base

> Thanks for your help!

My pleasure.

Just for the sake of details: without the removal of the
-msingle-pic-base I have the following register contents just before
'bl board_init_f' (start.S:219):
(gdb) info registers
r0 0x0 0
r1 0x0 0
r2 0x80003478 2147497080
r3 0xc1080000 3238526976
r4 0x80003484 2147497092
r5 0x80003480 2147497088
r6 0xc7fe9760 3355350880
r7 0xc7fbd000 3355168768
r8 0xc7ea8f8c 3354038156
r9 0xc10ac1c0 3238707648
r10 0xc10ac1c0 3238707648
r11 0xc7ea8f84 3354038148
r12 0x30 48
sp 0xc0000f80 0xc0000f80
lr 0x80000120 2147483936
pc 0xc1080088 0xc1080088 <reset+32>
fps 0x0 0
cpsr 0x600000d3 1610612947
(gdb)

and the System.map shows:
$cat System.map |grep got_base
c1080150 t relocate_got_base_r
c108017c t _got_base
c1080180 t _relocate_got_base_r
c10ac1c0 A __got_base

Best Regards,
Ben Gardiner

---
Nanometrics Inc.