Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -498,7 +498,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"; @@ -1322,6 +1333,13 @@ if (!First) return Off; + // Some loaders use -Ttext to set start address of text section. + // In that case behavior of GNU linkers inconsistent. bfd sets + // VA exactly to specified and stops aligning file offset. + // We match bfd here. + if (Config->SectionStartMap.count(".text")) + return Off; + // If two sections share the same PT_LOAD the file offset is calculated using // this formula: Off2 = Off1 + (VA2 - VA1). if (Sec == First) Index: test/ELF/ttext2.s =================================================================== --- test/ELF/ttext2.s +++ test/ELF/ttext2.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check that .text has VA 0x0. That matches bfd behavior. +# RUN: ld.lld -N -Ttext 0x0 %t -o %t1 +# RUN: llvm-readobj -s %t1 | FileCheck %s +# CHECK: Section { +# CHECK: Index: 1 +# CHECK: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0xE8 +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } + +.text +.globl _start +_start: + nop