Some software vendors (such as NVidia) ship proprietary program code for specialized hardware (e.g. GPUs) in vendor-specific PROGBITS sections (e.g. .nv_fatbin). Before this change, these section may have been placed between .rodata and .text, which leads to relocation overflows even when the actual program code is small because these vendor-specific sections can be quite big (e.g. .nv_fatbin can be >1GiB when including support for various GPU architectures).
Details
Diff Detail
Event Timeline
Normally the only things that refer to the stuff in .nv_* are static data structures in .rodata, so placing .nv_fatbin before that is the right thing to do, as long as it does not get in a way of something else.
does an output section have limited-range relocations referring to or from it? If so, move it to the end of the segment
What I am a bit concerned is that relocations in input sections can cause layout changes (a little surprise). The heuristic of output section sizes is similar.
A less ad-hoc rule is to implement INSERT BEFORE for orphan sections. It currently only works for a linker script (see test/ELF/linkerscript/insert-before.test). I prefer general INSERT BEFORE and INSERT AFTER because they make the fixed internal linker script logic a bit more flexible.
In GNU ld, INSERT BEFORE is not considered an external linker script. lld currently has script->hasSectionCommands = true; => this should be fixed. INSERT BEFORE provide a quick way for disturbing the section layout. They can be used as a workaround for other relocation overflow problems.
It is difficult to get a working executable with clang -fuse-ld=lld a.c -Wl,-T,a.x, because an application-like linker script needs to create PT_LOAD segment boundaries by explicitly mentioning the first section for each PT_LOAD segment. If such an alignment is omitted => sh_addr of the first section of one PT_LOAD is not correct -> the created PT_LOAD may have overlapping p_vaddr ranges (after modulo maxpagesize at ).
A skeleton linker script which should work with both -no-pie (image base (0x400000) is required and -pie (0x400000 is not required, but it does not hurt):
SECTIONS { . = SIZEOF_HEADERS + 0x400000; .rodata : { *(.rodata*) } .text : { *(.text*) } . = ALIGN(CONSTANT(MAXPAGESIZE)) + . % CONSTANT(MAXPAGESIZE); .fini_array : { *(.fini_array*) } . = ALIGN(CONSTANT(MAXPAGESIZE)) + . % CONSTANT(MAXPAGESIZE); .data : { *(.data*) } }
Created D74375 . I think INSERT [AFTER|BEFORE] is a great solution to this kind of problems..
I agree with MaskRay that if section layout of non-standard custom sections is important then a linker script, or linker script fragment is a cleaner way to accomplish it.