Overflow related to program headers

Hi folks!

I have some linker-script-related topic to discuss. Considering the following example (just a small reproducer):

.section data,"wa",@nobits
.zero 1
.section .second_in_section,"ax",@progbits
.zero 1
.section .first_in_section,"ax",@progbits
.zero 1
.globl _start
_start:

If I use the following linker script:

MEMORY { mem (r): org = 0x10000000, len = 0x00100000 }

SECTIONS {
  first_section 0x10000000 : { KEEP (*(.first_in_section)); } > mem
  second_section (0x10000000 +64) : { KEEP (*(.second_in_section)); } > mem
  /DISCARD/ : { KEEP (*(.text, data .comment, .symtab, .strtab)); }
}

I got the expected result:

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x001000 0x0000000010000000 0x0000000010000000 0x000041 0x000041 R E 0x1000
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x0

 Section to Segment mapping:
  Segment Sections...
   00     first_section second_section 
   01     
   None   .shstrtab 

However, if I invert the output section assignment:

MEMORY { mem (r): org = 0x10000000, len = 0x00100000 }

SECTIONS {
  second_section (0x10000000 +64) : { KEEP (*(.second_in_section)); } > mem
  first_section 0x10000000 : { KEEP (*(.first_in_section)); } > mem
  /DISCARD/ : { KEEP (*(.text, data .comment, .symtab, .strtab)); }
}

I ended up with the following result, with overflowed FileSiz and MemSiz:

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x001040 0x0000000010000040 0x0000000010000040 0xffffffffffffffc1 0xffffffffffffffc1 R E 0x1000
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x0

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   None   second_section first_section .shstrtab 

Gnu ld can handle this case:

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x001000 0x0000000010000000 0x0000000010000000 0x000041 0x000041 R E 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     second_section first_section 
   None   .symtab .strtab .shstrtab 

This reflects a silent behavior, that can appear in some complex linker scripts that sometimes can be really difficult to catch by inspecting the output sections (it can be scattered in several included linker script files).

Do you think it is interesting to have this sort of out-of-order capability in LLD? I think this can be interesting for the embedded world folks, so maybe @smithp35 may have an interesting view.

Regards!

I think this is a case of LLD assuming that all OutputSections assigned to a Program Header are in ascending order, and a subtraction ends up overflowing. I’m sure there was a Github issue with this already, with a suggested workaround that I don’t think was universally applicable.

Whether this is useful behaviour or not I think this is definitely worth an issue for as LLD is producing bad output. If it doesn’t support non-ascending output sections then it should give an error message.

I’m not particularly fond of the output that comes from GNU ld. We essentially have:

second_section  0x0000000010000040        0x1
 *(.second_in_section)
 .second_in_section
                0x0000000010000040        0x1 dat.o

first_section   0x0000000010000000        0x1
 *(.first_in_section)
 .first_in_section
                0x0000000010000000        0x1 dat.o

Which means the PT_LOAD program header no longer accurately describes the VMA of its contents, only the LMA. This may not be of concern to embedded users who aren’t going to use the program header anyway.

I would expect that this situation happens by accident rather than by intention though.

In summary I suggest raising an issue, or if you can find the existing one, tag your example on to it.

Hi @smithp35, thank you for your comments, I was not aware of this PT_LOAD implication. I will try to find the GitHub issue that you mentioned to attach those examples.

Regards.