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: [PATCH] Fix overlapping sections in ELF files when a memory segment has no contents


On Wed, May 23, 2018 at 02:09:11PM +0100, Jozef Lawrynowicz wrote:
> On targets which have small page size, or no concept of page size, memory
> segments in the output file may require little or no alignment.
> An optimization in bfd/elf.c:assign_file_positions_for_load_sections, to save
> some space in the output file when a segment has no contents, can cause sections
> to overlap on these targets.
> This was exposed when running the "simple objcopy of executable" test for
> msp430-elf with the -mlarge target flag, which failed due to different
> section and segment offsets between the original ELF file and the ELF file
> output from objcopy.
> 
> Here are the relevant parts of the "readelf -a" output of the linked executable
> from the above test:
> 
> ======
> Section Headers:
>   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
> ...
>   [ 2] .rodata           PROGBITS        00002000 000134 000090 00   A  0   0  2
> ...
>   [ 7] .bss              NOBITS          00000646 000136 00002c 00  WA  0   0  2
> ...
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   LOAD           0x000000 0x00000510 0x00000510 0x00134 0x00162 RW  0x4
>   LOAD           0x000134 0x00002000 0x00002000 0x00090 0x00090 R   0x4
> ...
>  Section to Segment mapping:
>   Segment Sections...
>    00     .bss
>    01     .rodata
> ======
> The first segment contains only .bss. .data has its VMA in this segment, but its
> LMA is elsewhere, which is partly why this segment has size, despite its
> sections having no contents. This segment also contains some ELF headers which
> is where the rest of the file size comes from.
> 
> As can be seen in the above readelf output, the offset of the .bss section
> (0x136), is not within the memory segment that's supposed to contain it. This
> segment ends at 0x134.

What does sh_offset for a .bss section mean?  The ELF gABI says:

sh_offset
    This member's value gives the byte offset from the beginning of
    the file to the first byte in the section. One section type,
    SHT_NOBITS described below, occupies no space in the file, and its
    sh_offset member locates the conceptual placement in the file.

You'll note the phrase "conceptual placement", and I'd say that 0x136
*is* in fact within the first PT_LOAD segment's conceptual placement
of its entire p_memsz.

> When objcopy copies this ELF file, the new ELF file has
> both the .rodata section offset, and the file offset for the segment containing
> .rodata, set to 0x138. File size for the segment containing .bss is also
> incremented to 0x136.

OK, so the code that objcopy uses to copy headers has a bug.  That is
what needs fixing rather than trying to avoid triggering the bug.  (At
least, someone needs to attempt the proper fix before implementing
work-arounds!  Please open a bugzilla with your testcase object file
attached.)

> The attached patch fixes the cause of the overlapping sections, by incrementing
> the segment filesize, and not decrementing output file offset, if it appears the
> next segment would start before the end of the current segment.


-- 
Alan Modra
Australia Development Lab, IBM


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