[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