Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -744,6 +744,13 @@ if (Sec->Type == SHT_DYNSYM || Sec->Type == SHT_STRTAB) return Rank | RF_ALLOC_FIRST; + // GPU binaries may grow quite large which may lead to relocation overflows if + // the section is placed between .text and regular data segments. Placing the + // section at the beginning of SHF_ALLOC, similarly to .dynstr/.dynsym above + // mitigates the problem. + if (Sec->Name == ".nv_fatbin") + return Rank |= RF_ALLOC_FIRST; + // Sort sections based on their access permission in the following // order: R, RX, RWX, RW. This order is based on the following // considerations: Index: lld/test/ELF/nv_fatbin-at-beginning.s =================================================================== --- /dev/null +++ lld/test/ELF/nv_fatbin-at-beginning.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t + +# RUN: ld.lld --hash-style=gnu -o %t1 %t -shared +# RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s + +# .nv_fatbin has the same priority as .dynsym/.dynstr and is expected to +# located before .rodata and .text +# CHECK-DAG: .nv_fatbin {{.*}} A +# CHECK-DAG: .dynsym {{.*}} A +# CHECK-DAG: .dynstr {{.*}} A +# CHECK: .rodata {{.*}} A +# CHECK: .text {{.*}} AX + +.section .rodata, "a" +.byte 1 + +.section .nv_fatbin, "a" +.byte 0