Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -482,7 +482,18 @@ template static bool compareSectionsNonScript(const OutputSectionBase *A, const OutputSectionBase *B) { - // Put .interp first because some loaders want to see that section + // Some loaders use -Ttext option to set .text section address. + // In that case we place it at the begining to be able to + // assign VA in a simple forward loop later. That is consistent + // with what GNU gold do. + if (Config->SectionStartMap.count(".text")) { + bool AIsText = A->getName() == ".text"; + bool BIsText = B->getName() == ".text"; + if (AIsText != BIsText) + return AIsText; + } + + // Put .interp early because some loaders want to see that section // on the first page of the executable file when loaded into memory. bool AIsInterp = A->getName() == ".interp"; bool BIsInterp = B->getName() == ".interp"; Index: test/ELF/ttext.s =================================================================== --- test/ELF/ttext.s +++ test/ELF/ttext.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: ld.lld -N %t -o %t1 +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .rodata 00000008 00000000002000e8 DATA +# CHECK-NEXT: 2 .text 00000001 00000000002000f0 TEXT DATA + +## Check that sections does not intersect if -Ttext used. +# RUN: ld.lld -N -Ttext 0x2000e8 %t -o %t1 +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s --check-prefix=TEXT +# TEXT: Sections: +# TEXT-NEXT: Idx Name Size Address Type +# TEXT-NEXT: 0 00000000 0000000000000000 +# TEXT-NEXT: 1 .text 00000001 00000000002000e8 TEXT DATA +# TEXT-NEXT: 2 .rodata 00000008 00000000002000e9 DATA + +.text +.globl _start +_start: + nop + +.section .rodata,"a" + .quad 1