// Process PHDRS and FILEHDR keywords because they are not
// real output sections and cannot be added in the following loop.
+ std::vector<size_t> DefPhdrIds;
for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
PhdrEntry<ELFT> &Phdr = Ret.back();
Phdr.H.p_paddr = Cmd.LMAExpr(0);
Phdr.HasLMA = true;
}
+
+ // If output section command doesn't specify any segments,
+ // and we haven't previously assigned any section to segment,
+ // then we simply assign section to the very first load segment.
+ // Below is an example of such linker script:
+ // PHDRS { seg PT_LOAD; }
+ // SECTIONS { .aaa : { *(.aaa) } }
+ if (DefPhdrIds.empty() && Phdr.H.p_type == PT_LOAD)
+ DefPhdrIds.push_back(Ret.size() - 1);
}
// Add output sections to program headers.
- PhdrEntry<ELFT> *Load = nullptr;
- uintX_t Flags = PF_R;
for (OutputSectionBase<ELFT> *Sec : *OutputSections) {
if (!(Sec->getFlags() & SHF_ALLOC))
break;
std::vector<size_t> PhdrIds = getPhdrIndices(Sec->getName());
- if (!PhdrIds.empty()) {
- // Assign headers specified by linker script
- for (size_t Id : PhdrIds) {
- Ret[Id].add(Sec);
- if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
- Ret[Id].H.p_flags |= Sec->getPhdrFlags();
- }
- } else {
- // If we have no load segment or flags've changed then we want new load
- // segment.
- uintX_t NewFlags = Sec->getPhdrFlags();
- if (Load == nullptr || Flags != NewFlags) {
- Load = &*Ret.emplace(Ret.end(), PT_LOAD, NewFlags);
- Flags = NewFlags;
- }
- Load->add(Sec);
+ if (PhdrIds.empty())
+ PhdrIds = std::move(DefPhdrIds);
+
+ // Assign headers specified by linker script
+ for (size_t Id : PhdrIds) {
+ Ret[Id].add(Sec);
+ if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
+ Ret[Id].H.p_flags |= Sec->getPhdrFlags();
}
+ DefPhdrIds = std::move(PhdrIds);
}
return Ret;
}
# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
# RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_RANDOMIZE; } \
# RUN: SECTIONS { . = SIZEOF_HEADERS; \
+# RUN: .text : { *(.text) } \
# RUN: .openbsd.randomdata : { *(.openbsd.randomdata) } : rand }" > %t.script
# RUN: ld.lld --script %t.script %t.o -o %t
# RUN: llvm-readobj --program-headers -s %t | FileCheck %s
# CHECK: ProgramHeader {
# CHECK: Type: PT_OPENBSD_RANDOMIZE (0x65A3DBE6)
-# CHECK-NEXT: Offset: 0x94
-# CHECK-NEXT: VirtualAddress: 0x94
-# CHECK-NEXT: PhysicalAddress: 0x94
+# CHECK-NEXT: Offset: 0x74
+# CHECK-NEXT: VirtualAddress: 0x74
+# CHECK-NEXT: PhysicalAddress: 0x74
# CHECK-NEXT: FileSize: 8
# CHECK-NEXT: MemSize: 8
# CHECK-NEXT: Flags [ (0x4)
# RUN: .text : {*(.text*)} :all \
# RUN: .foo : {*(.foo.*)} :all \
# RUN: .data : {*(.data.*)} :all}" > %t.script
-
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
+
+# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS FLAGS (0x1);} \
+# RUN: SECTIONS { \
+# RUN: . = 0x10000200; \
+# RUN: .text : {*(.text*)} :all \
+# RUN: .foo : {*(.foo.*)} \
+# RUN: .data : {*(.data.*)} }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s
+
# CHECK: ProgramHeaders [
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: PF_X (0x1)
# CHECK-NEXT: ]
+# DEFHDR: ProgramHeaders [
+# DEFHDR-NEXT: ProgramHeader {
+# DEFHDR-NEXT: Type: PT_LOAD (0x1)
+# DEFHDR-NEXT: Offset: 0x0
+# DEFHDR-NEXT: VirtualAddress: 0x10000000
+# DEFHDR-NEXT: PhysicalAddress: 0x10000000
+# DEFHDR-NEXT: FileSize: 521
+# DEFHDR-NEXT: MemSize: 521
+# DEFHDR-NEXT: Flags [ (0x1)
+# DEFHDR-NEXT: PF_X (0x1)
+# DEFHDR-NEXT: ]
+# DEFHDR-NEXT: Alignment: 4096
+# DEFHDR-NEXT: }
+
.global _start
_start:
nop
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=AT %s
+# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS ;} \
+# RUN: SECTIONS { \
+# RUN: . = 0x10000200; \
+# RUN: .text : {*(.text*)} :all \
+# RUN: .foo : {*(.foo.*)} \
+# RUN: .data : {*(.data.*)} }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s
+
# CHECK: ProgramHeaders [
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# INT-PHDRS-NEXT: }
# INT-PHDRS-NEXT: ]
+# DEFHDR: ProgramHeaders [
+# DEFHDR-NEXT: ProgramHeader {
+# DEFHDR-NEXT: Type: PT_LOAD (0x1)
+# DEFHDR-NEXT: Offset: 0x0
+# DEFHDR-NEXT: VirtualAddress: 0x10000000
+# DEFHDR-NEXT: PhysicalAddress: 0x10000000
+# DEFHDR-NEXT: FileSize: 521
+# DEFHDR-NEXT: MemSize: 521
+# DEFHDR-NEXT: Flags [ (0x7)
+# DEFHDR-NEXT: PF_R (0x4)
+# DEFHDR-NEXT: PF_W (0x2)
+# DEFHDR-NEXT: PF_X (0x1)
+# DEFHDR-NEXT: ]
+
.global _start
_start:
nop