[PATCH] Use offsets instead of addresses in ELF_SECTION_IN_SEGMENT

Alan Hayward Alan.Hayward@arm.com
Thu May 24 13:18:00 GMT 2018



> On 23 May 2018, at 14:39, Alan Modra <amodra@gmail.com> wrote:
> 

<snip>

>> 
>> For example, here is the readelf output of a small binary I compiled. Note the
>> address for ER_DATA with PROGBITS. In the existing code this will use sh_addr,
>> incorrectly loading it to 0xead4. What we want instead is to use (p_vaddr +
>> sh_offset - p_offset), which is (0x8000 + 0x2b08 - 0x34), which is 0xaad4.
>> 
>> 
>> Section Headers:
>>  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
>>  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
>>  [ 1] ER_CODE           PROGBITS        00008000 000034 002ad4 00  AX  0   0  4
>>  [ 2] ER_DATA           PROGBITS        0000ead4 002b08 000020 00  WA  0   0  4
>>  [ 3] ER_DATA           NOBITS          0000eaf4 002b28 00015c 00  WA  0   0  4
>>  [ 4] ARM_LIB_STACKHEAP NOBITS          00040000 002b28 001000 00  WA  0   0  1
>>  [ 5] .debug_abbrev     PROGBITS        00000000 002b28 000065 00      0   0  1
>>  [ 6] .debug_frame      PROGBITS        00000000 002b8d 000d9c 00      0   0  1
>>  [ 7] .debug_info       PROGBITS        00000000 003929 00006e 00      0   0  1
>>  [ 8] .debug_line       PROGBITS        00000000 003997 00003c 00      0   0  1
>>  [ 9] .debug_pubnames   PROGBITS        00000000 0039d3 000029 00      0   0  1
>>  [10] .debug_pubtypes   PROGBITS        00000000 0039fc 000023 00      0   0  1
>>  [11] .debug_str        PROGBITS        00000000 003a1f 00008b 00      0   0  1
>>  [12] .symtab           SYMTAB          00000000 003aac 002d60 10     13 498  4
>>  [13] .strtab           STRTAB          00000000 00680c 001f54 00      0   0  1
>>  [14] .note             NOTE            00000000 008760 000020 00      0   0  4
>>  [15] .comment          PROGBITS        00000000 008780 0003e0 00      0   0  1
>>  [16] .shstrtab         STRTAB          00000000 008b60 0000ac 00      0   0  1
>> 
>> Program Headers:
>>  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>>  LOAD           0x000034 0x00008000 0x00008000 0x02af4 0x03c50 RWE 0x4
>> 
>> 
>> All of this is still within the elf spec, but clearly different from the GNU
>> linker - the idea was to get a patch that allowed us the safely work for both
>> without any horrible “if gnu ... else if armlinker ...” code.
> 
> I think you may need to detect these armlinker segments.  The problem
> with disabling the sh_addr comparisons is that sh_offset for
> SHT_NOBITS sections doesn't really have a physical meaning.  You don't
> load SHT_NOBITS from file after all.  Your armlinker binaries might
> have the convention that sh_offset is given values as if a segment's
> bss part actually existed on disk, but not all ELF binaries will
> follow that convention.  What's more, the convention breaks down in
> the presence of multiple tightly packed PT_LOAD segments where any but
> the last has p_memsz > p_filesz.  That situation would lead to
> SHT_NOBITS sections having sh_offset values corresponding to the
> PT_LOAD segment past the one to which they actually belong.
> 
> If the armlinker only ever creates one PT_LOAD segment, it might be
> possible to accommodate it by disabling check_vma whenever there is
> just one PT_LOAD segment.

Unfortunately, there is one PT_LOAD section per load region, and the
number of load regions is arbitrary and defined by the user.

I’ve been looking at ways to reliably detect if the armlinker was used.
Sadly, there is nothing in the elf file to reliably detect armlinker arm
binaries vs gnu linker arm binaries.

Am I right in thinking that both the zero offsets for SHT_NOBITS and the
tightly packed binaries are things that could appear in an Arm linux binary?
(I suspect you could write a linker script to do it). If so, then it wouldn’t
be safe to do something like "if (Arm and Linux) check_vma=false”.


Alan.



More information about the Binutils mailing list