Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -21,6 +21,7 @@ #include "ScriptParser.h" #include "Strings.h" #include "SymbolTable.h" +#include "Target.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ELF.h" #include "llvm/Support/FileSystem.h" @@ -222,6 +223,7 @@ // Assign addresses as instructed by linker script SECTIONS sub-commands. Dot = Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); uintX_t ThreadBssOffset = 0; + OutputSectionBase* PrevSec = nullptr; for (SectionsCommand &Cmd : Opt.Commands) { if (Cmd.Kind == ExprKind) { @@ -245,9 +247,14 @@ } if (Sec->getFlags() & SHF_ALLOC) { - Dot = alignTo(Dot, Sec->getAlignment()); + assert(Sec->getPtLoadAnchor()); + uintX_t align = PrevSec == nullptr || + PrevSec->getPtLoadAnchor() == Sec->getPtLoadAnchor() ? + Sec->getAlignment() : Target->PageSize; + Dot = alignTo(Dot, align); Sec->setVA(Dot); Dot += Sec->getSize(); + PrevSec = Sec; continue; } } Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -67,6 +67,7 @@ uintX_t getVA() const { return Header.sh_addr; } void setFileOffset(uintX_t Off) { Header.sh_offset = Off; } void setSHName(unsigned Val) { Header.sh_name = Val; } + void setPtLoadAnchor(OutputSectionBase* anchor) { PtLoadAnchor = anchor; } void writeHeaderTo(Elf_Shdr *SHdr); StringRef getName() { return Name; } @@ -89,6 +90,7 @@ if (Alignment > Header.sh_addralign) Header.sh_addralign = Alignment; } + OutputSectionBase* getPtLoadAnchor() const { return PtLoadAnchor; } // If true, this section will be page aligned on disk. // Typically the first section of each PT_LOAD segment has this flag. @@ -103,6 +105,8 @@ protected: StringRef Name; Elf_Shdr Header; + // First section in ELF segment + OutputSectionBase* PtLoadAnchor; }; template class GotSection final : public OutputSectionBase { Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -37,6 +37,7 @@ memset(&Header, 0, sizeof(Elf_Shdr)); Header.sh_type = Type; Header.sh_flags = Flags; + PtLoadAnchor = nullptr; } template Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1022,6 +1022,8 @@ if (!Hdr.First) Hdr.First = Sec; Hdr.H.p_align = std::max(Hdr.H.p_align, Sec->getAlignment()); + if (Hdr.H.p_type == PT_LOAD) + Sec->setPtLoadAnchor(Hdr.First); }; // The first phdr entry is PT_PHDR which describes the program header itself. @@ -1045,7 +1047,7 @@ Phdr Note(PT_NOTE, PF_R); for (OutputSectionBase *Sec : OutputSections) { if (!(Sec->getFlags() & SHF_ALLOC)) - break; + continue; // If we meet TLS section then we create TLS header // and put all TLS sections inside for futher use when Index: test/ELF/arm-data-prel.s =================================================================== --- test/ELF/arm-data-prel.s +++ test/ELF/arm-data-prel.s @@ -49,7 +49,7 @@ // Word1 Inline table entry EHT Inline Personality Routine #0 // CHECK: Name: .ARM.exidx // CHECK: SectionData ( -// CHECK: 0000: FCFFFF7F B0B0B080 +// CHECK: 0000: F4F0FF7F B0B0B080 // CHECK: ) // The expected value of the exception table is @@ -59,5 +59,5 @@ // pop r11, r14 // CHECK: Name: .ARM.exidx.TEST1 // CHECK: SectionData ( -// CHECK: 0000: 08000000 80849B80 +// CHECK: 0000: F80F0000 80849B80 // CHECK: ) Index: test/ELF/end.s =================================================================== --- test/ELF/end.s +++ test/ELF/end.s @@ -36,13 +36,13 @@ // NOBSS-NEXT: SHF_ALLOC // NOBSS-NEXT: SHF_WRITE // NOBSS-NEXT: ] -// NOBSS-NEXT: Address: 0x159 +// NOBSS-NEXT: Address: 0x1000 // NOBSS-NEXT: Offset: // NOBSS-NEXT: Size: 2 // NOBSS: ] // NOBSS: Symbols [ // NOBSS: Name: _end -// NOBSS-NEXT: Value: 0x15B +// NOBSS-NEXT: Value: 0x1002 // NOBSS: ] // If the layout of the sections is changed, "_end" should point to the end of allocated address space. @@ -60,13 +60,13 @@ // TEXTATEND-NEXT: SHF_ALLOC // TEXTATEND-NEXT: SHF_EXECINSTR // TEXTATEND-NEXT: ] -// TEXTATEND-NEXT: Address: 0x160 +// TEXTATEND-NEXT: Address: 0x1000 // TEXTATEND-NEXT: Offset: // TEXTATEND-NEXT: Size: 1 // TEXTATEND: ] // TEXTATEND: Symbols [ // TEXTATEND: Name: _end -// TEXTATEND-NEXT: Value: 0x161 +// TEXTATEND-NEXT: Value: 0x1001 // TEXTATEND: ] .global _start,_end Index: test/ELF/linkerscript-repsection-va.s =================================================================== --- test/ELF/linkerscript-repsection-va.s +++ test/ELF/linkerscript-repsection-va.s @@ -8,8 +8,8 @@ # CHECK-NEXT: Idx Name Size Address Type # CHECK-NEXT: 0 00000000 0000000000000000 # CHECK-NEXT: 1 .foo 00000004 0000000000000158 DATA -# CHECK-NEXT: 2 .foo 00000004 000000000000015c DATA -# CHECK-NEXT: 3 .text 00000001 0000000000000160 TEXT DATA +# CHECK-NEXT: 2 .foo 00000004 0000000000001000 DATA +# CHECK-NEXT: 3 .text 00000001 0000000000002000 TEXT DATA .global _start _start: Index: test/ELF/linkerscript-sections-keep.s =================================================================== --- test/ELF/linkerscript-sections-keep.s +++ test/ELF/linkerscript-sections-keep.s @@ -13,7 +13,7 @@ # SECGC-NEXT: Idx Name Size Address Type # SECGC-NEXT: 0 00000000 0000000000000000 # SECGC-NEXT: 1 .text 00000007 0000000000000158 TEXT DATA -# SECGC-NEXT: 2 .temp 00000004 000000000000015f DATA +# SECGC-NEXT: 2 .temp 00000004 0000000000001000 DATA ## Now apply KEEP command to preserve the section. # RUN: echo "SECTIONS { \ @@ -27,8 +27,8 @@ # SECNOGC-NEXT: Idx Name Size Address Type # SECNOGC-NEXT: 0 00000000 0000000000000000 # SECNOGC-NEXT: 1 .text 00000007 0000000000000158 TEXT DATA -# SECNOGC-NEXT: 2 .keep 00000004 000000000000015f DATA -# SECNOGC-NEXT: 3 .temp 00000004 0000000000000163 DATA +# SECNOGC-NEXT: 2 .keep 00000004 0000000000001000 DATA +# SECNOGC-NEXT: 3 .temp 00000004 0000000000001004 DATA ## A section name matches two entries in the SECTIONS directive. The ## first one doesn't have KEEP, the second one does. If section that have @@ -43,7 +43,7 @@ # MIXED1-NEXT: 0 00000000 0000000000000000 # MIXED1-NEXT: 1 .keep 00000004 0000000000000120 DATA # MIXED1-NEXT: 2 .temp 00000004 0000000000000124 DATA -# MIXED1-NEXT: 3 .text 00000007 0000000000000128 TEXT DATA +# MIXED1-NEXT: 3 .text 00000007 0000000000001000 TEXT DATA # MIXED1-NEXT: 4 .symtab 00000060 0000000000000000 # MIXED1-NEXT: 5 .shstrtab 0000002d 0000000000000000 # MIXED1-NEXT: 6 .strtab 00000012 0000000000000000 @@ -62,7 +62,7 @@ # MIXED2-NEXT: 0 00000000 0000000000000000 # MIXED2-NEXT: 1 .nokeep 00000004 0000000000000120 DATA # MIXED2-NEXT: 2 .temp 00000004 0000000000000124 DATA -# MIXED2-NEXT: 3 .text 00000007 0000000000000128 TEXT DATA +# MIXED2-NEXT: 3 .text 00000007 0000000000001000 TEXT DATA # MIXED2-NEXT: 4 .symtab 00000060 0000000000000000 # MIXED2-NEXT: 5 .shstrtab 0000002f 0000000000000000 # MIXED2-NEXT: 6 .strtab 00000012 0000000000000000 Index: test/ELF/linkerscript-va.s =================================================================== --- test/ELF/linkerscript-va.s +++ test/ELF/linkerscript-va.s @@ -9,7 +9,7 @@ # CHECK-NEXT: 0 00000000 0000000000000000 # CHECK-NEXT: 1 .foo 00000004 0000000000000120 DATA # CHECK-NEXT: 2 .boo 00000004 0000000000000124 DATA -# CHECK-NEXT: 3 .text 00000001 0000000000000128 TEXT DATA +# CHECK-NEXT: 3 .text 00000001 0000000000001000 TEXT DATA .global _start _start: Index: test/ELF/phdr-align.s =================================================================== --- test/ELF/phdr-align.s +++ test/ELF/phdr-align.s @@ -63,8 +63,8 @@ # CHECK-NEXT: SHF_ALLOC # CHECK-NEXT: SHF_EXECINSTR # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x160 -# CHECK-NEXT: Offset: 0x160 +# CHECK-NEXT: Address: 0x1000 +# CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: Size: 1 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0