[U-Boot] Relocation size penalty calculation

Graeme Russ
2009-10-13T11:21:05Z

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

>> [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

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

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

I don't think .dynamic is needed due to the exporting of section addresses
from the linker script

Regards,

Graeme