[U-Boot] Relocation size penalty calculation

Graeme Russ
2009-10-13T20:06:56Z

On Tue, Oct 13, 2009 at 10:53 PM, Joakim Tjernlund
<joakim.tjernlund@transmode.se> wrote:
> Graeme Russ <graeme.russ@gmail.com> wrote on 13/10/2009 13:21:05:
>> On Sun, Oct 11, 2009 at 11:51 PM, Joakim Tjernlund
>> <joakim.tjernlund@transmode.se> wrote:
>> > Graeme Russ <graeme.russ@gmail.com> wrote on 11/10/2009 12:47:19:
>>
>> [Massive Snip :)]
>>
>> >
>> >>
>> >> So, all that is left are .dynsym and .dynamic ...
>> >> .dynsym
>> >> - Contains 70 entries (16 bytes each, 1120 bytes)
>> >> - 44 entries mimic those entries in .got which are not relocated
>> >> - 21 entries are the remaining symbols exported from the linker
>> >> script
>> >> - 4 entries are labels defined in inline asm and used in C
>> > Try adding proper asm declarations. Look at what gcc
>> > generates for a function/variable and mimic these.
>>
>> Thanks - Now .dynsym contains only exports from the linker script
> :)
>>
>> >
>> >> - 1 entry is a NULL entry
>> >>
>> >> .dynamic
>> >> - 88 bytes
>> >> - Array of Elf32_Dyn
>> >> - typedef struct {
>> >> Elf32_Sword d_tag;
>> >> union {
>> >> Elf32_Word d_val;
>> >> Elf32_Addr d_ptr;
>> >> } d_un;
>> >> } Elf32_Dyn;
>> >> - 0x11 entries
>> >> [00] 0x00000010, 0x00000000 DT_SYMBOLIC, (ignored)
>> >> [01] 0x00000004, 0x38059994 DT_HASH, points to .hash
>> >> [02] 0x00000005, 0x380595AB DT_STRTAB, points to .dynstr
>> >> [03] 0x00000006, 0x3805BDCC DT_SYMTAB, points to .dynsym
>> >> [04] 0x0000000A, 0x000003E6 DT_STRSZ, size of .dynstr
>> >> [05] 0x0000000B, 0x00000010 DT_SYMENT, ???
>> >> [06] 0x00000015, 0x00000000 DT_DEBUG, ???
>> >> [07] 0x00000011, 0x3805A8F4 DT_REL, points to .rel.text
>> >> [08] 0x00000012, 0x000014D8 DT_RELSZ, ???
>> > How big DT_REL is
>> >> [09] 0x00000013, 0x00000008 DT_RELENT, ???
>> > hmm, cannot remeber :)
>>
>> How big an entry in DT_REL is
>
> Right, how could I forget :)
>>
>> >> [0a] 0x00000016, 0x00000000 DT_TEXTREL, ???
>> > Oops, you got text relocations. This is generally a bad thing.
>> > TEXTREL is commonly caused by asm code that arent truly pic so it needs
>> > to modify the .text segment to adjust for relocation.
>> > You should get rid of this one. Look for DT_TEXTREL in .o files to find
>> > the culprit.
>> >
>>
>> Alas I cannot - The relocations are a result of loading a register with a
>> return address when calling show_boot_progress in the very early stages of
>> initialisation prior to the stack becoming available. The x86 does not
>> allow direct access to the IP so the only way to find the 'current
>> execution address' is to 'call' to the next instruction and pop the return
>> address off the stack
>
> hmm, same as ppc but that in it self should not cause a TEXREL, should it?
> Ahh, the 'call' is absolute, not relative? I guess there is some way around it
> but it is not important ATM I guess.
>
> Evil idea, skip -fpic et. all and add the full reloc procedure
> to relocate by rewriting directly in TEXT segment. Then you save space
> but you need more relocation code. Something like dl_do_reloc from
> uClibc. Wonder how much extra code that would be? Not too much I think.
>

With the following flags

PLATFORM_RELFLAGS += -fvisibility=hidden
PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
PLATFORM_LDFLAGS += -pic --emit-relocs -Bsymbolic -Bsymbolic-functions

I get no .got, but a lot of R_386_PC32 and R_386_32 relocations. I think
this might mean I need the symbol table in the binary in order to resolve
them

>>
>> This is not a problem because this is very low-level init that is not
>> called once relocated into RAM - These relocations can be safely ignored
>
>>
>> >> [0b] 0x6FFFFFFA, 0x00000236 ???, Entries in .rel.dyn
>> >> [0c] 0x00000000, 0x00000000 DT_NULL, End of Array
>> >> [0d] 0x00000000, 0x00000000 DT_NULL, End of Array
>> >> [0e] 0x00000000, 0x00000000 DT_NULL, End of Array
>> >> [0f] 0x00000000, 0x00000000 DT_NULL, End of Array
>> >> [10] 0x00000000, 0x00000000 DT_NULL, End of Array
>> >>
>> >> I think some more investigation into the need for .dynsym and .dynamic is
>> >> still required...
>>
>> .dynsym may still be required if only for accessing the __u_boot_cmd
>> structure. However, I may be able to hack that a little and not create a
>> __u_boot_cmd symbol in the linker script (create some other temporary
>> symbol) and populate __u_boot_cmd with a valid value after relocation. It
>> will look a little weird, but may mean not loading this section into RAM
>
> Why do you need to much around with u_boot_cmd at all? Now that relocation
> works you should be able to drop all that code/linker stuff?
>
>>
>> Other than that, .dynsym is now only needed to locate the sections during
>> the relocation phase and can be kept in flash and not copied to RAM
>
> Still occupies space in the *bin image though.
>
>