Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -297,6 +297,14 @@ uintX_t AFlags = A->getFlags(); uintX_t BFlags = B->getFlags(); + // The TLS spec says that the linker can assume that TLS sections are R/W. Do + // this so we can generate a minimal PT_TLS Phdr. Non-allocated TLS sections + // are ignored because they shouldn't be in the middle of allocated sections. + if (AFlags & SHF_TLS && AFlags & SHF_ALLOC) + AFlags |= SHF_WRITE; + if (BFlags & SHF_TLS && BFlags & SHF_ALLOC) + BFlags |= SHF_WRITE; + // Allocatable sections go first to reduce the total PT_LOAD size and // so debug info doesn't change addresses in actual code. bool AIsAlloc = AFlags & SHF_ALLOC; @@ -316,6 +324,15 @@ if (AIsWritable != BIsWritable) return BIsWritable; + // The TLS initialization block needs to be a single contiguous block in a R/W + // PT_LOAD, so stick TLS sections directly before R/W sections. The TLS NOBITS + // sections are placed here as they don't take up virtual address space in the + // PT_LOAD. + bool AIsTLS = AFlags & SHF_TLS; + bool BIsTLS = BFlags & SHF_TLS; + if (AIsTLS != BIsTLS) + return AIsTLS; + // For a corresponding reason, put non exec sections first (the program // header PT_LOAD is not executable). bool AIsExec = AFlags & SHF_EXECINSTR; Index: test/elf2/section-layout.s =================================================================== --- test/elf2/section-layout.s +++ test/elf2/section-layout.s @@ -9,10 +9,25 @@ .text _start: -.section h,"" -.section g,"",@nobits -.section f,"aw",@nobits -.section e,"aw" +.section v,"T",@nobits +.section u,"T" +.section t,"x",@nobits +.section s,"x" +.section r,"w",@nobits +.section q,"w" +.section p,"wx",@nobits +.section o,"wx" +.section n,"",@nobits +.section m,"" + +.section l,"awx",@nobits +.section k,"awx" +.section j,"aw",@nobits +.section i,"aw" +.section h,"aT",@nobits +.section g,"awT",@nobits +.section f,"aT" +.section e,"awT" .section d,"ax",@nobits .section c,"ax" .section b,"a",@nobits @@ -22,7 +37,26 @@ // CHECK: Name: b // CHECK: Name: c // CHECK: Name: d -// CHECK: Name: e + +// TLS sections are only sorted on NOBITS. // CHECK: Name: f +// CHECK: Name: e // CHECK: Name: h // CHECK: Name: g + +// CHECK: Name: i +// CHECK: Name: j +// CHECK: Name: k +// CHECK: Name: l + +// Non allocated sections are in input order. +// CHECK: Name: v +// CHECK: Name: u +// CHECK: Name: t +// CHECK: Name: s +// CHECK: Name: r +// CHECK: Name: q +// CHECK: Name: p +// CHECK: Name: o +// CHECK: Name: n +// CHECK: Name: m