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; @@ -258,7 +258,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 @@ -238,8 +238,14 @@ template void OutputSection::writeTo(uint8_t *Buf) { Loc = Buf; - if (uint32_t Filler = Script::X->getFiller(this->Name)) - fill(Buf, this->Size, Filler); + + // Fill gaps with the values specified in 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 Filler = Script::X->getFiller(this->Name)) + fill(Buf, this->Size, *Filler); + else if (Flags & SHF_EXECINSTR && Target->TrapInstr != 0) + fill(Buf, this->Size, Target->TrapInstr); auto Fn = [=](InputSection *IS) { IS->writeTo(Buf); }; forEach(Sections.begin(), Sections.end(), Fn); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2213,7 +2213,8 @@ template void MipsRldMapSection::writeTo(uint8_t *Buf) { // Apply filler from linker script. - uint64_t Filler = Script::X->getFiller(this->Name); + Optional Fill = Script::X->getFiller(this->Name); + uint64_t Filler = Fill ? *Fill : 0; Filler = (Filler << 32) | Filler; memcpy(Buf, &Filler, getSize()); } Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -98,6 +98,8 @@ virtual void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; virtual void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const; + + uint32_t TrapInstr = 0; }; uint64_t getPPC64TocBase(); Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -355,6 +355,8 @@ 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 @@ // 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 Index: test/ELF/default-fill.s =================================================================== --- test/ELF/default-fill.s +++ test/ELF/default-fill.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +# Verify that the fill between sections has a default of interrupt instructions +# (0xcc on x86/x86_64) + +# 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 | FileCheck %s + +# 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 | FileCheck %s + +# CHECK: Contents of section .data: +# CHECK-NEXT: 33000000 00000000 00000000 00000000 +# CHECK-NEXT: 44 +# CHECK: Contents of section .text: +# CHECK-NEXT: 11cccccc cccccccc cccccccc cccccccc +# CHECK-NEXT: 22 + +.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 Index: test/ELF/linkerscript/excludefile.s =================================================================== --- test/ELF/linkerscript/excludefile.s +++ test/ELF/linkerscript/excludefile.s @@ -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 Index: test/ELF/linkerscript/fill-exec-sections.s =================================================================== --- test/ELF/linkerscript/fill-exec-sections.s +++ test/ELF/linkerscript/fill-exec-sections.s @@ -0,0 +1,48 @@ +# 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. +# 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 + +## ...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 +# 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 + +.section .noexec.1,"a" +.align 16 +.byte 0x77 + +.section .noexec.2,"a" +.align 16 +.byte 0x77