Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -129,7 +129,7 @@ Expr SubalignExpr; std::vector> Commands; std::vector Phdrs; - uint32_t Filler = 0; + llvm::Optional Filler; ConstraintKind Constraint = ConstraintKind::NoConstraint; std::string Location; std::string MemoryRegionName; @@ -257,7 +257,7 @@ std::vector createPhdrs(); bool ignoreInterpSection(); - uint32_t getFiller(StringRef Name); + llvm::Optional getFiller(StringRef Name); void writeDataBytes(StringRef Name, uint8_t *Buf); bool hasLMA(StringRef Name); bool shouldKeep(InputSectionBase *S); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -839,12 +839,13 @@ }) == Opt.PhdrsCommands.end(); } -template uint32_t LinkerScript::getFiller(StringRef Name) { +template +Optional LinkerScript::getFiller(StringRef Name) { for (const std::unique_ptr &Base : Opt.Commands) if (auto *Cmd = dyn_cast(Base.get())) if (Cmd->Name == Name) return Cmd->Filler; - return 0; + return Optional(); } template Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -236,10 +236,23 @@ memcpy(Buf + I, V, Size - I); } +// Fills the gaps between sections, at first fills whole buffer +// with target specific one-byte trap padding if section is executable. +// That was done because we want to avoid bogus disassembly output which +// happens if we do not fill gaps with specific nop trap instructions. +// After above function applies linker script's fill expression which always +// overrides default filling if present. +template +static void fillSectionGaps(OutputSection *Sec, uint8_t *Buf) { + if (Sec->Flags & SHF_EXECINSTR) + memset(Buf, Target->PaddingValue, Sec->Size); + if (Optional Filler = Script::X->getFiller(Sec->Name)) + fill(Buf, Sec->Size, *Filler); +} + template void OutputSection::writeTo(uint8_t *Buf) { Loc = Buf; - if (uint32_t Filler = Script::X->getFiller(this->Name)) - fill(Buf, this->Size, Filler); + fillSectionGaps(this, Buf); auto Fn = [=](InputSection *IS) { IS->writeTo(Buf); }; forEach(Sections.begin(), Sections.end(), Fn); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2213,8 +2213,9 @@ template void MipsRldMapSection::writeTo(uint8_t *Buf) { // Apply filler from linker script. - uint64_t Filler = Script::X->getFiller(this->Name); - Filler = (Filler << 32) | Filler; + uint64_t Filler = 0; + if (Optional F = Script::X->getFiller(this->Name)) + Filler = ((uint64_t)*F << 32) | (uint64_t)*F; memcpy(Buf, &Filler, getSize()); } Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -62,6 +62,10 @@ unsigned PageSize = 4096; unsigned DefaultMaxPageSize = 4096; + // Used for filling gaps in executable sections. Assumed to be + // target specific one byte trap instruction. + uint8_t PaddingValue = 0x0; + // On FreeBSD x86_64 the first page cannot be mmaped. // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64 // installs that is 65536, so the first 15 pages cannot be used. Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -355,6 +355,7 @@ PltEntrySize = 16; PltHeaderSize = 16; TlsGdRelaxSkip = 2; + PaddingValue = 0xcc; } RelExpr X86TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const { @@ -644,6 +645,7 @@ PltEntrySize = 16; PltHeaderSize = 16; TlsGdRelaxSkip = 2; + PaddingValue = 0xcc; // Align to the large page size (known as a superpage or huge page). // FreeBSD automatically promotes large, superpage-aligned allocations. DefaultImageBase = 0x200000; Index: test/ELF/linkerscript/excludefile.s =================================================================== --- test/ELF/linkerscript/excludefile.s +++ test/ELF/linkerscript/excludefile.s @@ -13,11 +13,9 @@ # 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: _potato: # CHECK-NEXT: : 90 nop # CHECK-NEXT: : 90 nop -# CHECK-NEXT: : 00 00 addb %al, (%rax) # CHECK: tomato: # CHECK-NEXT: : b8 01 00 00 00 movl $1, %eax @@ -31,7 +29,6 @@ # 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: _potato: # EXCLUDE-NEXT: : 90 nop # EXCLUDE-NEXT: : 90 nop Index: test/ELF/linkerscript/sections-padding-exec.s =================================================================== --- test/ELF/linkerscript/sections-padding-exec.s +++ test/ELF/linkerscript/sections-padding-exec.s @@ -0,0 +1,40 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check that paddings of executable sections are filled with trap byte. +# 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: 66cccccc cccccccc cccccccc cccccccc +# EXEC-NEXT: 66 + +## Non-executable sections are not affected. +# RUN: echo "SECTIONS { .noexec : { *(.noexec*) } }" > %t2.script +# RUN: ld.lld -o %t2.out --script %t2.script %t +# RUN: llvm-objdump -s %t2.out | FileCheck %s --check-prefix=NOEXEC +# NOEXEC: 0000 77000000 00000000 00000000 00000000 +# NOEXEC: 0010 77 + +## Check that =fill expression still overrides the default filler. +# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x11223344 }" > %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 66223344 11223344 11223344 11223344 +# OVERRIDE-NEXT: 0010 66 + +.section .exec.1,"ax" +.align 16 +.byte 0x66 + +.section .exec.2,"ax" +.align 16 +.byte 0x66 + +.section .noexec.1,"a" +.align 16 +.byte 0x77 + +.section .noexec.2,"a" +.align 16 +.byte 0x77 Index: test/ELF/sections-padding-exec-i686.s =================================================================== --- test/ELF/sections-padding-exec-i686.s +++ test/ELF/sections-padding-exec-i686.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t + +## Check that paddings of executable sections are filled with trap byte. +# RUN: ld.lld -o %t.out %t +# RUN: llvm-objdump -s %t.out | FileCheck %s +# CHECK: Contents of section .text: +# CHECK-NEXT: 66cccccc cccccccc cccccccc cccccccc +# CHECK-NEXT: 66 + +.section .text.1,"ax" +.align 16 +.byte 0x66 + +.section .text.2,"ax" +.align 16 +.byte 0x66 Index: test/ELF/sections-padding-exec.s =================================================================== --- test/ELF/sections-padding-exec.s +++ test/ELF/sections-padding-exec.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check that paddings of executable sections are filled with trap byte. +# RUN: ld.lld -o %t.out %t +# RUN: llvm-objdump -s %t.out | FileCheck %s +# CHECK: Contents of section .text: +# CHECK-NEXT: 66cccccc cccccccc cccccccc cccccccc +# CHECK-NEXT: 66 + +.section .text.1,"ax" +.align 16 +.byte 0x66 + +.section .text.2,"ax" +.align 16 +.byte 0x66