forked from OSchip/llvm-project
Revert r299635 because it exposed a latent bug.
llvm-svn: 299655
This commit is contained in:
parent
9fa169601f
commit
d983180778
|
@ -862,12 +862,12 @@ bool LinkerScript::ignoreInterpSection() {
|
|||
return true;
|
||||
}
|
||||
|
||||
Optional<uint32_t> LinkerScript::getFiller(StringRef Name) {
|
||||
uint32_t LinkerScript::getFiller(StringRef Name) {
|
||||
for (BaseCommand *Base : Opt.Commands)
|
||||
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
|
||||
if (Cmd->Name == Name)
|
||||
return Cmd->Filler;
|
||||
return None;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
|
||||
|
|
|
@ -112,7 +112,7 @@ struct OutputSectionCommand : BaseCommand {
|
|||
Expr SubalignExpr;
|
||||
std::vector<BaseCommand *> Commands;
|
||||
std::vector<StringRef> Phdrs;
|
||||
llvm::Optional<uint32_t> Filler;
|
||||
uint32_t Filler = 0;
|
||||
ConstraintKind Constraint = ConstraintKind::NoConstraint;
|
||||
std::string Location;
|
||||
std::string MemoryRegionName;
|
||||
|
@ -262,7 +262,7 @@ public:
|
|||
std::vector<PhdrEntry> createPhdrs();
|
||||
bool ignoreInterpSection();
|
||||
|
||||
llvm::Optional<uint32_t> getFiller(StringRef Name);
|
||||
uint32_t getFiller(StringRef Name);
|
||||
bool hasLMA(StringRef Name);
|
||||
bool shouldKeep(InputSectionBase *S);
|
||||
void assignOffsets(OutputSectionCommand *Cmd);
|
||||
|
|
|
@ -225,9 +225,6 @@ void OutputSection::sortCtorsDtors() {
|
|||
// Fill [Buf, Buf + Size) with Filler. Filler is written in big
|
||||
// endian order. This is used for linker script "=fillexp" command.
|
||||
static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
|
||||
if (Filler == 0)
|
||||
return;
|
||||
|
||||
uint8_t V[4];
|
||||
write32be(V, Filler);
|
||||
size_t I = 0;
|
||||
|
@ -236,44 +233,17 @@ static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
|
|||
memcpy(Buf + I, V, Size - I);
|
||||
}
|
||||
|
||||
uint32_t OutputSection::getFill() {
|
||||
// Determine what to fill gaps between InputSections with, as specified by the
|
||||
// linker script. If nothing is specified and this is an executable section,
|
||||
// fall back to trap instructions to prevent bad diassembly and detect invalid
|
||||
// jumps to padding.
|
||||
if (Optional<uint32_t> Filler = Script->getFiller(Name))
|
||||
return *Filler;
|
||||
if (Flags & SHF_EXECINSTR)
|
||||
return Target->TrapInstr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
|
||||
Loc = Buf;
|
||||
if (uint32_t Filler = Script->getFiller(this->Name))
|
||||
fill(Buf, this->Size, Filler);
|
||||
|
||||
uint32_t Filler = getFill();
|
||||
|
||||
// Write leading padding.
|
||||
size_t FillSize = Sections.empty() ? Size : Sections[0]->OutSecOff;
|
||||
fill(Buf, FillSize, Filler);
|
||||
|
||||
parallelFor(0, Sections.size(), [=](size_t I) {
|
||||
InputSection *Sec = Sections[I];
|
||||
Sec->writeTo<ELFT>(Buf);
|
||||
|
||||
// Fill gaps between sections with the specified fill value.
|
||||
uint8_t *Start = Buf + Sec->OutSecOff + Sec->getSize();
|
||||
uint8_t *End;
|
||||
if (I + 1 == Sections.size())
|
||||
End = Buf + Size;
|
||||
else
|
||||
End = Buf + Sections[I + 1]->OutSecOff;
|
||||
fill(Start, End - Start, Filler);
|
||||
});
|
||||
parallelForEach(Sections.begin(), Sections.end(),
|
||||
[=](InputSection *IS) { IS->writeTo<ELFT>(Buf); });
|
||||
|
||||
// Linker scripts may have BYTE()-family commands with which you
|
||||
// can write arbitrary bytes to the output. Process them if any.
|
||||
Script->writeDataBytes(Name, Buf);
|
||||
Script->writeDataBytes(this->Name, Buf);
|
||||
}
|
||||
|
||||
static uint64_t getOutFlags(InputSectionBase *S) {
|
||||
|
|
|
@ -81,7 +81,6 @@ public:
|
|||
void sort(std::function<int(InputSectionBase *S)> Order);
|
||||
void sortInitFini();
|
||||
void sortCtorsDtors();
|
||||
uint32_t getFill();
|
||||
template <class ELFT> void writeTo(uint8_t *Buf);
|
||||
template <class ELFT> void finalize();
|
||||
void assignOffsets();
|
||||
|
|
|
@ -2180,11 +2180,7 @@ MipsRldMapSection::MipsRldMapSection()
|
|||
|
||||
void MipsRldMapSection::writeTo(uint8_t *Buf) {
|
||||
// Apply filler from linker script.
|
||||
Optional<uint32_t> Fill = Script->getFiller(this->Name);
|
||||
if (!Fill || *Fill == 0)
|
||||
return;
|
||||
|
||||
uint64_t Filler = *Fill;
|
||||
uint64_t Filler = Script->getFiller(this->Name);
|
||||
Filler = (Filler << 32) | Filler;
|
||||
memcpy(Buf, &Filler, getSize());
|
||||
}
|
||||
|
|
|
@ -349,8 +349,6 @@ X86TargetInfo::X86TargetInfo() {
|
|||
PltEntrySize = 16;
|
||||
PltHeaderSize = 16;
|
||||
TlsGdRelaxSkip = 2;
|
||||
// 0xCC is the "int3" (call debug exception handler) instruction.
|
||||
TrapInstr = 0xcccccccc;
|
||||
}
|
||||
|
||||
RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
|
||||
|
@ -649,8 +647,6 @@ template <class ELFT> X86_64TargetInfo<ELFT>::X86_64TargetInfo() {
|
|||
// Align to the large page size (known as a superpage or huge page).
|
||||
// FreeBSD automatically promotes large, superpage-aligned allocations.
|
||||
DefaultImageBase = 0x200000;
|
||||
// 0xCC is the "int3" (call debug exception handler) instruction.
|
||||
TrapInstr = 0xcccccccc;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
|
|
@ -90,10 +90,6 @@ public:
|
|||
|
||||
bool NeedsThunks = false;
|
||||
|
||||
// A 4-byte field corresponding to one or more trap instructions, used to pad
|
||||
// executable OutputSections.
|
||||
uint32_t TrapInstr = 0;
|
||||
|
||||
virtual RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
|
||||
RelExpr Expr) const;
|
||||
virtual void relaxGot(uint8_t *Loc, uint64_t Val) const;
|
||||
|
|
|
@ -1790,7 +1790,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
|
|||
|
||||
// The .eh_frame_hdr depends on .eh_frame section contents, therefore
|
||||
// it should be written after .eh_frame is written.
|
||||
if (EhFrameHdr && !EhFrameHdr->Sections.empty())
|
||||
if (EhFrameHdr)
|
||||
EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# REQUIRES: x86
|
||||
# Verify that the fill between sections has a default of interrupt instructions
|
||||
# (0xcc on x86/x86_64) for executable sections and zero for other sections.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
|
||||
# RUN: ld.lld %t1.o -o %t1.elf
|
||||
# RUN: llvm-objdump -s %t1.elf > %t1.sections
|
||||
# RUN: FileCheck %s --input-file %t1.sections --check-prefix=TEXT
|
||||
# RUN: FileCheck %s --input-file %t1.sections --check-prefix=DATA
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t2.o
|
||||
# RUN: ld.lld %t2.o -o %t2.elf
|
||||
# RUN: llvm-objdump -s %t2.elf > %t2.sections
|
||||
# RUN: FileCheck %s --input-file %t2.sections --check-prefix=TEXT
|
||||
# RUN: FileCheck %s --input-file %t2.sections --check-prefix=DATA
|
||||
|
||||
# TEXT: Contents of section .text:
|
||||
# TEXT-NEXT: 11cccccc cccccccc cccccccc cccccccc
|
||||
# TEXT-NEXT: 22
|
||||
# DATA: Contents of section .data:
|
||||
# DATA-NEXT: 33000000 00000000 00000000 00000000
|
||||
# DATA-NEXT: 44
|
||||
|
||||
.section .text.1,"ax",@progbits
|
||||
.align 16
|
||||
.byte 0x11
|
||||
|
||||
.section .text.2,"ax",@progbits
|
||||
.align 16
|
||||
.byte 0x22
|
||||
|
||||
.section .data.1,"a",@progbits
|
||||
.align 16
|
||||
.byte 0x33
|
||||
|
||||
.section .data.2,"a",@progbits
|
||||
.align 16
|
||||
.byte 0x44
|
|
@ -13,13 +13,11 @@
|
|||
# CHECK: _start:
|
||||
# CHECK-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax
|
||||
# CHECK-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi
|
||||
# CHECK-NEXT: : cc int3
|
||||
# CHECK-NEXT: : cc int3
|
||||
# CHECK-NEXT: : 00 00 addb %al, (%rax)
|
||||
# CHECK: _potato:
|
||||
# CHECK-NEXT: : 90 nop
|
||||
# CHECK-NEXT: : 90 nop
|
||||
# CHECK-NEXT: : cc int3
|
||||
# CHECK-NEXT: : cc int3
|
||||
# CHECK-NEXT: : 00 00 addb %al, (%rax)
|
||||
# CHECK: tomato:
|
||||
# CHECK-NEXT: : b8 01 00 00 00 movl $1, %eax
|
||||
|
||||
|
@ -33,8 +31,7 @@
|
|||
# EXCLUDE: _start:
|
||||
# EXCLUDE-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax
|
||||
# EXCLUDE-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi
|
||||
# EXCLUDE-NEXT: : cc int3
|
||||
# EXCLUDE-NEXT: : cc int3
|
||||
# EXCLUDE-NEXT: : 00 00 addb %al, (%rax)
|
||||
# EXCLUDE: _potato:
|
||||
# EXCLUDE-NEXT: : 90 nop
|
||||
# EXCLUDE-NEXT: : 90 nop
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
|
||||
## Check that padding of executable sections are filled with trap bytes if not
|
||||
## otherwise specified in the script.
|
||||
# RUN: echo "SECTIONS { .exec : { *(.exec*) } }" > %t.script
|
||||
# RUN: ld.lld -o %t.out --script %t.script %t
|
||||
# RUN: llvm-objdump -s %t.out | FileCheck %s --check-prefix=EXEC
|
||||
# EXEC: 0000 66cccccc cccccccc cccccccc cccccccc
|
||||
# EXEC-NEXT: 0010 66
|
||||
|
||||
## Check that a fill expression or command overrides the default filler...
|
||||
# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x11223344 }" > %t2.script
|
||||
# RUN: ld.lld -o %t2.out --script %t2.script %t
|
||||
# RUN: llvm-objdump -s %t2.out | FileCheck %s --check-prefix=OVERRIDE
|
||||
# RUN: echo "SECTIONS { .exec : { FILL(0x11223344); *(.exec*) } }" > %t3.script
|
||||
# RUN: ld.lld -o %t3.out --script %t3.script %t
|
||||
# RUN: llvm-objdump -s %t3.out | FileCheck %s --check-prefix=OVERRIDE
|
||||
# OVERRIDE: Contents of section .exec:
|
||||
# OVERRIDE-NEXT: 0000 66112233 44112233 44112233 44112233
|
||||
# OVERRIDE-NEXT: 0010 66
|
||||
|
||||
## ...even for a value of zero.
|
||||
# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x00000000 }" > %t4.script
|
||||
# RUN: ld.lld -o %t4.out --script %t4.script %t
|
||||
# RUN: llvm-objdump -s %t4.out | FileCheck %s --check-prefix=ZERO
|
||||
# RUN: echo "SECTIONS { .exec : { FILL(0x00000000); *(.exec*) } }" > %t5.script
|
||||
# RUN: ld.lld -o %t5.out --script %t5.script %t
|
||||
# RUN: llvm-objdump -s %t5.out | FileCheck %s --check-prefix=ZERO
|
||||
# ZERO: Contents of section .exec:
|
||||
# ZERO-NEXT: 0000 66000000 00000000 00000000 00000000
|
||||
# ZERO-NEXT: 0010 66
|
||||
|
||||
.section .exec.1,"ax"
|
||||
.align 16
|
||||
.byte 0x66
|
||||
|
||||
.section .exec.2,"ax"
|
||||
.align 16
|
||||
.byte 0x66
|
|
@ -3,7 +3,6 @@
|
|||
# RUN: echo "SECTIONS { \
|
||||
# RUN: .out : { \
|
||||
# RUN: FILL(0x11111111); \
|
||||
# RUN: . += 2; \
|
||||
# RUN: *(.aaa) \
|
||||
# RUN: . += 4; \
|
||||
# RUN: *(.bbb) \
|
||||
|
@ -16,7 +15,7 @@
|
|||
# RUN: llvm-objdump -s %t | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .out:
|
||||
# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222
|
||||
# CHECK-NEXT: aa222222 22bb2222 22222222 2222
|
||||
|
||||
.text
|
||||
.globl _start
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x1122 }" > %t.script
|
||||
# RUN: ld.lld -o %t.out --script %t.script %t
|
||||
# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
|
||||
# YES: 66000011 22000011 22000011 22000011
|
||||
# YES: 66001122 00001122 00001122 00001122
|
||||
|
||||
## Confirming that address was correct:
|
||||
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99887766 }" > %t.script
|
||||
# RUN: ld.lld -o %t.out --script %t.script %t
|
||||
# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES2 %s
|
||||
# YES2: 66998877 66998877 66998877 66998877
|
||||
# YES2: 66887766 99887766 99887766 99887766
|
||||
|
||||
## Default padding value is 0x00:
|
||||
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } }" > %t.script
|
||||
|
@ -23,7 +23,7 @@
|
|||
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =777 }" > %t.script
|
||||
# RUN: ld.lld -o %t.out --script %t.script %t
|
||||
# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=DEC %s
|
||||
# DEC: 66000003 09000003 09000003 09000003
|
||||
# DEC: 66000309 00000309 00000309 00000309
|
||||
|
||||
## Invalid hex value:
|
||||
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script
|
||||
|
|
Loading…
Reference in New Issue