forked from OSchip/llvm-project
[ELF] Choose default segment when it is not specified
Linker scripts may specify PHDRS, but not specify section to segment assignments, i.e: PHDRS { seg PT_LOAD; } SECTIONS { .sec1 {} : seg .sec2 {} } In such case linker should still choose some segment for .sec2 section. This patch will add .sec2 to previously opened segments (seg) or to the very first PT_LOAD segment, if no section-to-segment assignments has been made Differential revision: https://reviews.llvm.org/D24795 llvm-svn: 284600
This commit is contained in:
parent
37dabc2427
commit
ce30b1c78e
|
@ -682,6 +682,7 @@ std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() {
|
|||
|
||||
// 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();
|
||||
|
@ -695,33 +696,33 @@ std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
# 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)
|
||||
|
|
|
@ -6,9 +6,18 @@
|
|||
# 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)
|
||||
|
@ -22,6 +31,20 @@
|
|||
# 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
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
# 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)
|
||||
|
@ -70,6 +79,20 @@
|
|||
# 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
|
||||
|
|
Loading…
Reference in New Issue