[lld] r299755 - [ELF] Recommit r299635 to pad x86 executable sections with 0xcc
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 7 03:36:43 PDT 2017
Author: jhenderson
Date: Fri Apr 7 05:36:42 2017
New Revision: 299755
URL: http://llvm.org/viewvc/llvm-project?rev=299755&view=rev
Log:
[ELF] Recommit r299635 to pad x86 executable sections with 0xcc
This follows r299748 which fixed a latent bug the original commit exposed.
Added:
lld/trunk/test/ELF/default-fill.s
- copied unchanged from r299654, lld/trunk/test/ELF/default-fill.s
lld/trunk/test/ELF/linkerscript/fill-exec-sections.s
- copied unchanged from r299654, lld/trunk/test/ELF/linkerscript/fill-exec-sections.s
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/linkerscript/excludefile.s
lld/trunk/test/ELF/linkerscript/fill.s
lld/trunk/test/ELF/linkerscript/sections-padding.s
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Apr 7 05:36:42 2017
@@ -871,12 +871,12 @@ bool LinkerScript::ignoreInterpSection()
return true;
}
-uint32_t LinkerScript::getFiller(StringRef Name) {
+Optional<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 0;
+ return None;
}
static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Apr 7 05:36:42 2017
@@ -126,7 +126,7 @@ struct OutputSectionCommand : BaseComman
Expr SubalignExpr;
std::vector<BaseCommand *> Commands;
std::vector<StringRef> Phdrs;
- uint32_t Filler = 0;
+ llvm::Optional<uint32_t> Filler;
ConstraintKind Constraint = ConstraintKind::NoConstraint;
std::string Location;
std::string MemoryRegionName;
@@ -264,7 +264,7 @@ public:
std::vector<PhdrEntry> createPhdrs();
bool ignoreInterpSection();
- uint32_t getFiller(StringRef Name);
+ llvm::Optional<uint32_t> getFiller(StringRef Name);
bool hasLMA(StringRef Name);
bool shouldKeep(InputSectionBase *S);
void assignOffsets(OutputSectionCommand *Cmd);
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Apr 7 05:36:42 2017
@@ -224,6 +224,9 @@ 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;
@@ -232,17 +235,44 @@ static void fill(uint8_t *Buf, size_t Si
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);
- parallelForEach(Sections.begin(), Sections.end(),
- [=](InputSection *IS) { IS->writeTo<ELFT>(Buf); });
+ 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);
+ });
// Linker scripts may have BYTE()-family commands with which you
// can write arbitrary bytes to the output. Process them if any.
- Script->writeDataBytes(this->Name, Buf);
+ Script->writeDataBytes(Name, Buf);
}
static uint64_t getOutFlags(InputSectionBase *S) {
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Apr 7 05:36:42 2017
@@ -81,6 +81,7 @@ 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();
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Apr 7 05:36:42 2017
@@ -2180,7 +2180,11 @@ MipsRldMapSection::MipsRldMapSection()
void MipsRldMapSection::writeTo(uint8_t *Buf) {
// Apply filler from linker script.
- uint64_t Filler = Script->getFiller(this->Name);
+ Optional<uint32_t> Fill = Script->getFiller(this->Name);
+ if (!Fill || *Fill == 0)
+ return;
+
+ uint64_t Filler = *Fill;
Filler = (Filler << 32) | Filler;
memcpy(Buf, &Filler, getSize());
}
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Apr 7 05:36:42 2017
@@ -349,6 +349,8 @@ 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 {
@@ -647,6 +649,8 @@ template <class ELFT> X86_64TargetInfo<E
// 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>
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Apr 7 05:36:42 2017
@@ -90,6 +90,10 @@ 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;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Apr 7 05:36:42 2017
@@ -1790,7 +1790,7 @@ template <class ELFT> void Writer<ELFT>:
// The .eh_frame_hdr depends on .eh_frame section contents, therefore
// it should be written after .eh_frame is written.
- if (EhFrameHdr)
+ if (EhFrameHdr && !EhFrameHdr->Sections.empty())
EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
}
Modified: lld/trunk/test/ELF/linkerscript/excludefile.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/excludefile.s?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/excludefile.s (original)
+++ lld/trunk/test/ELF/linkerscript/excludefile.s Fri Apr 7 05:36:42 2017
@@ -13,11 +13,13 @@
# 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: : 00 00 addb %al, (%rax)
+# CHECK-NEXT: : cc int3
+# CHECK-NEXT: : cc int3
# CHECK: _potato:
# CHECK-NEXT: : 90 nop
# CHECK-NEXT: : 90 nop
-# CHECK-NEXT: : 00 00 addb %al, (%rax)
+# CHECK-NEXT: : cc int3
+# CHECK-NEXT: : cc int3
# CHECK: tomato:
# CHECK-NEXT: : b8 01 00 00 00 movl $1, %eax
@@ -31,7 +33,8 @@
# 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: : 00 00 addb %al, (%rax)
+# EXCLUDE-NEXT: : cc int3
+# EXCLUDE-NEXT: : cc int3
# EXCLUDE: _potato:
# EXCLUDE-NEXT: : 90 nop
# EXCLUDE-NEXT: : 90 nop
Modified: lld/trunk/test/ELF/linkerscript/fill.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/fill.s?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/fill.s (original)
+++ lld/trunk/test/ELF/linkerscript/fill.s Fri Apr 7 05:36:42 2017
@@ -3,6 +3,7 @@
# RUN: echo "SECTIONS { \
# RUN: .out : { \
# RUN: FILL(0x11111111); \
+# RUN: . += 2; \
# RUN: *(.aaa) \
# RUN: . += 4; \
# RUN: *(.bbb) \
@@ -15,7 +16,7 @@
# RUN: llvm-objdump -s %t | FileCheck %s
# CHECK: Contents of section .out:
-# CHECK-NEXT: aa222222 22bb2222 22222222 2222
+# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222
.text
.globl _start
Modified: lld/trunk/test/ELF/linkerscript/sections-padding.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/sections-padding.s?rev=299755&r1=299754&r2=299755&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/sections-padding.s (original)
+++ lld/trunk/test/ELF/linkerscript/sections-padding.s Fri Apr 7 05:36:42 2017
@@ -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: 66001122 00001122 00001122 00001122
+# YES: 66000011 22000011 22000011 22000011
## 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: 66887766 99887766 99887766 99887766
+# YES2: 66998877 66998877 66998877 66998877
## 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: 66000309 00000309 00000309 00000309
+# DEC: 66000003 09000003 09000003 09000003
## Invalid hex value:
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script
More information about the llvm-commits
mailing list