This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: binutils 2.20.1+gcc 4.4.3 on mipsel question


KertÃsz Csaba <csaba.kertesz@gmail.com> writes:
> I have not hacked binutils before and I have a current problem what I
> do not understand and probably somebody can help or point me to the
> right direction. I have the following cross-compiling environment for
> a mipsel target supporting only static binaries. The current toolchain
> what I try to make it work:
>
> binutils 2.20.1
> gcc/g++ 4.4.3
> newlib 2.18
>
> The old environment had g++ 3.3.6 and binutils 2.15, but now it is
> needed to update the toolchain, but the target has a special ELF
> format, what is generated by some old perl scripts and I should now
> update them.
>
> What happens: A static binary (normal.elf) without relocation and an
> other binary (out of the same object files) with relocation
> (reloc.elf) are generated. The perl script reads the offset of the
> symbols from the output of the "readelf -r reloc.elf" with type
> R_MIPS_32. The section of each loaded symbol is read in binary form
> from the normal.elf and a long integer (4 bytes) is extracted from the
> corresponding section in the position of the read offset previously.
> Let's see an example:
>
> Reloc.elf:
>
> Relocation section '.rel.rodata' at offset 0x1fad64 contains 2430 entries:
> ÂOffset Info Type Sym.Value Sym. Name
> 00001244Â 00000402 R_MIPS_32ÂÂÂÂÂÂÂÂ 00000000ÂÂ .text
>
> Normal elf:
>
> [12] .rel.rodata      PROGBITS        00402000 11b9e0 002244 00  WA  0   0  8
>
> The .rel.rodata section is loaded from the normal.elf from the file
> position 0x1fad64 in binary form. In the loaded section data, a long
> int (4 bytes in VAX order, let us denote by addr) is extracted from
> the position 0x1244 (see above, it is the relocation offset of the
> symbol). Let's say the extracted addr = 0x4d4321. With the perl
> script, a table is produced finally for each symbol with the following
> numbers:
> 1. section_address+relocated_offset-relocation offset ->
> 0x402000+0x1244-0x400000 = 0x3244
> 2. addr == 0 ? 0 : addr-relocation_offset -> 0x4d4321-0x400000 = 0xd4321
>
> I can see from some headers about purpose of these numbers:
> 1. offset from base address of segment
> 2. relocation addend.  (value to be used during relocation)
>
> Now, with the new toolchain, some addr numbers are much less than the
> relocation offset (e.g. 0xa or 0x5a28 etc.) or much bigger than the
> relocation offset (0xafc40020). Something seems to broken at this
> point for me and the second calculation gives quite insane numbers.
> Can somebody help me what can be wrong? The best solution would be to
> read the full source codes of the different binutils+gcc versions, but
> it would not seem to me a short journey... :(

Just so I understand: is reloc.elf generated using -r?  If so, then yeah,
the offsets in the -r output don't necessarily correspond to those in
the fully-linked binary.  (TBH, I'm surprised they were ever close
enough to work, so perhaps I'm missing something.  But the number of
features that cause the -r output to differ from the fully-linked
output has been steadily increasing over the years.)

Have you considered linking normal.elf with -q (aka --emit-relocs)
instead?  That tells the linker to preserve the original relocations.
If you're worried about binary size, you can strip the (static)
relocations later using objdump -S.

I'm not sure this process is ever going to be completely reliable
though.  You'll also need to compile with -fpie, -fPIE, -fpic or -fPIC,
if you aren't already, otherwise GCC will use things like R_MIPS_HI16
and R_MIPS_LO16 rather than R_MIPS_32.

Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]