[U-Boot] Relocation size penalty calculation

Joakim Tjernlund joakim.tjernlund at transmode.se
Sat Oct 17 14:32:05 CEST 2009


Graeme Russ <graeme.russ at gmail.com> wrote on 17/10/2009 07:17:04:
>

[SNIP]

>
> Apologies if this is getting way off-topic for a simple boot loader, but
> this is information I have gathered from far and wide over the net. I am
> surprised that there isn't a web site out there on 'How to create a
> relocatable boot loader'...

:), now you can write one :)

>
> OK, its all starting to come together now - It helps when you look at the
> right files ;)
>
> Firstly, u-boot.map
>
>                 0x380589a0                __rel_dyn_start = .
>
> .rel.dyn        0x380589a0     0x42b0
>  *(.rel.dyn)
>  .rel.got       0x00000000        0x0 cpu/i386/start.o
>  .rel.plt       0x00000000        0x0 cpu/i386/start.o
>  .rel.text      0x380589a0     0x2e28 cpu/i386/start.o
>  .rel.start16   0x3805b7c8       0x10 cpu/i386/start.o
>  .rel.data      0x3805b7d8      0xc18 cpu/i386/start.o
>  .rel.rodata    0x3805c3f0      0x360 cpu/i386/start.o
>  .rel.u_boot_cmd
>                 0x3805c750      0x500 cpu/i386/start.o
>                 0x3805cc50                __rel_dyn_end = .
>
>
> And the output of readelf...
>
> Section Headers:
>   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
>   [ 0]                   NULL            00000000 000000 000000 00      0   0  0
>   [ 1] .text             PROGBITS        38040000 001000 0118a4 00  AX  0   0  4
>   [ 2] .rel.text         REL             00000000 066c68 005d00 08     40   1  4
>   [ 3] .rodata           PROGBITS        380518a4 0128a4 005da5 00   A  0   0  4
>   [ 4] .rel.rodata       REL             00000000 06c968 000360 08     40   3  4
>   [ 5] .interp           PROGBITS        38057649 018649 000013 00   A  0   0  1
>   [ 6] .dynstr           STRTAB          3805765c 01865c 0001ee 00   A  0   0  1
>   [ 7] .hash             HASH            3805784c 01884c 0000cc 04   A 11   0  4
>   [ 8] .data             PROGBITS        38057918 018918 000a3c 00  WA  0   0  4
>   [ 9] .rel.data         REL             00000000 06ccc8 000c18 08     40   8  4
>   [10] .got.plt          PROGBITS        38058354 019354 00000c 04  WA  0   0  4
>   [11] .dynsym           DYNSYM          38058360 019360 000200 10   A  6   1  4
>   [12] .dynamic          DYNAMIC         38058560 019560 000080 08  WA  6   0  4
>   [13] .u_boot_cmd       PROGBITS        380585e0 0195e0 0003c0 00  WA  0   0  4
>   [14] .rel.u_boot_cmd   REL             00000000 06d8e0 000500 08     40  13  4
>   [15] .bss              NOBITS          3805cc50 01ec50 001a34 00  WA  0   0  4
>   [16] .bios             PROGBITS        00000000 01e000 00053e 00  AX  0   0  1
>   [17] .rel.bios         REL             00000000 06dde0 0000c0 08     40  16  4
>   [18] .rel.dyn          REL             380589a0 0199a0 0042b0 08   A 11   0  4
>   [19] .start16          PROGBITS        0000f800 01e800 000110 00  AX  0   0  1
>   [20] .rel.start16      REL             00000000 06dea0 000038 08     40  19  4
>   [21] .resetvec         PROGBITS        0000fff0 01eff0 000010 00  AX  0   0  1
>   [22] .rel.resetvec     REL             00000000 06ded8 000008 08     40  21  4
>
> ...
>
> Relocation section '.rel.text' at offset 0x66c68 contains 2976 entries:
>  Offset     Info    Type            Sym.Value  Sym. Name
> 38040010  00000101 R_386_32          38040000   .text
> 3804001e  00000101 R_386_32          38040000   .text
> 38040028  00000101 R_386_32          38040000   .text
> 3804003f  00000101 R_386_32          38040000   .text
> 38040051  00000101 R_386_32          38040000   .text
> 38040075  00000101 R_386_32          38040000   .text
> 38040085  00000101 R_386_32          38040000   .text
> 3804009d  0003e602 R_386_PC32        380403fa   load_uboot
> 380400a6  00000101 R_386_32          38040000   .text
> 38040015  00029f02 R_386_PC32        3804bdd8   early_board_init
> 38040023  0003f702 R_386_PC32        3804bdda   show_boot_progress_asm
>
> ...
>
> Relocation section '.rel.rodata' at offset 0x6c968 contains 108 entries:
>  Offset     Info    Type            Sym.Value  Sym. Name
> 38051908  00000201 R_386_32          380518a4   .rodata
> 38051938  00000201 R_386_32          380518a4   .rodata
> 38051968  00000201 R_386_32          380518a4   .rodata
> 38051998  00000201 R_386_32          380518a4   .rodata
> 380519c8  00000201 R_386_32          380518a4   .rodata
> 380519f8  00000201 R_386_32          380518a4   .rodata
>
> ...
>
> Relocation section '.rel.dyn' at offset 0x199a0 contains 2134 entries:
>  Offset     Info    Type            Sym.Value  Sym. Name
> 0000f838  00000008 R_386_RELATIVE
> 0000f846  00000008 R_386_RELATIVE
> 38040010  00000008 R_386_RELATIVE
> 3804001e  00000008 R_386_RELATIVE
> 38040028  00000008 R_386_RELATIVE
> 3804003f  00000008 R_386_RELATIVE
> 38040051  00000008 R_386_RELATIVE
> 38040075  00000008 R_386_RELATIVE
> 38040085  00000008 R_386_RELATIVE
>
> Notice that, apart from .rel.dyn, non of the .rel.* sections have the
> A (Allocated) flag set - They do not end up in the stripped binary image.
> .rel.dyn is allocated in the binary image with all the R_386_PC32 entries
> from the other .rel section are discarded and the R_386_32 have been
> 'converted' to R_386_RELATIVE which are simple to adjust (locate in memory
> and adjust by the relocation offset)

Ah, they are converted to relative. Wonder if all archs do this?
If so one only will need two reloc functions, one for Rel and
one for Rela relocs.

>
> The relocation fixup is really easy:
>
>    Elf32_Rel *rel_dyn_start = (Elf32_Rel *)&__rel_dyn_start;
>    Elf32_Rel *rel_dyn_end = (Elf32_Rel *)&__rel_dyn_end;
>    Elf32_Rel *re;
>
>    for (re = rel_dyn_start; re < rel_dyn_end; re++)
>    {
>       if (re->r_offset >= TEXT_BASE)
>          if (*(ulong *)re->r_offset >= TEXT_BASE)
>             *(ulong *)(re->r_offset - rel_offset) -= (Elf32_Addr)rel_offset;
>    }

Do you need the TEXT_BASE stuff or is it just a precaution?
Not sure if you need some test for NULL to handle weak undefined symbols though.

> The size penalty is ~17kB of extra data (which is not copied to RAM) and
> a tiny amount of relocation code (easily offset by removal of other fixups
> such as the command table fixup

17kB, how does that compare to the -fPIC version?

>
> Any without using the pic flag in gcc, there is no GOT and no associated
> performance penalty.

Yep :)

>
> Thanks for everyone's help (especially Jocke and Bill)

NP, will we see a patch soon?

 Jocke



More information about the U-Boot mailing list