summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Haarman <llvm@inglorion.net>2018-06-28 15:22:40 +0000
committerBob Haarman <llvm@inglorion.net>2018-06-28 15:22:40 +0000
commitc103156c606d76b4f1a8d424b2f37a423ad34c47 (patch)
treecfcbaf651ea8332f3817f97e88edd7c197f38bda
parentf7ad8bfbad4a095a0b9b4378da023573ef854418 (diff)
downloadbcm5719-llvm-c103156c606d76b4f1a8d424b2f37a423ad34c47.tar.gz
bcm5719-llvm-c103156c606d76b4f1a8d424b2f37a423ad34c47.zip
lld-link: align sections to 16 bytes if referenced from the gfids table
Summary: Control flow guard works best when targets it checks are 16-byte aligned. Microsoft's link.exe helps ensure this by aligning code from sections that are referenced from the gfids table to 16 bytes when linking with -guard:cf, even if the original section specifies a smaller alignment. This change implements that behavior in lld-link. See https://crbug.com/857012 for more details. Reviewers: ruiu, hans, thakis, zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D48690 llvm-svn: 335864
-rw-r--r--lld/COFF/Writer.cpp5
-rw-r--r--lld/test/COFF/Inputs/guardcf-align-foobar.yaml51
-rw-r--r--lld/test/COFF/guardcf-align.s45
3 files changed, 101 insertions, 0 deletions
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index efb471ecaa0..a9950e4cc85 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1045,6 +1045,11 @@ void Writer::createGuardCFTables() {
if (Config->Entry)
addSymbolToRVASet(AddressTakenSyms, cast<Defined>(Config->Entry));
+ // Ensure sections referenced in the gfid table are 16-byte aligned.
+ for (const ChunkAndOffset &C : AddressTakenSyms)
+ if (C.InputChunk->Alignment < 16)
+ C.InputChunk->Alignment = 16;
+
maybeAddRVATable(std::move(AddressTakenSyms), "__guard_fids_table",
"__guard_fids_count");
diff --git a/lld/test/COFF/Inputs/guardcf-align-foobar.yaml b/lld/test/COFF/Inputs/guardcf-align-foobar.yaml
new file mode 100644
index 00000000000..7878c459a4f
--- /dev/null
+++ b/lld/test/COFF/Inputs/guardcf-align-foobar.yaml
@@ -0,0 +1,51 @@
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .text.foo
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 31C0C3
+ - Name: .text.bar
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: FFE1
+symbols:
+ - Name: .text.foo
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 3
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3963538403
+ Number: 1
+ - Name: .text.bar
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 2
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 1143549852
+ Number: 2
+ - Name: foo
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: bar
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/lld/test/COFF/guardcf-align.s b/lld/test/COFF/guardcf-align.s
new file mode 100644
index 00000000000..a0caabc92b0
--- /dev/null
+++ b/lld/test/COFF/guardcf-align.s
@@ -0,0 +1,45 @@
+# RUN: llvm-mc -triple x86_64-windows-msvc -filetype=obj -o %t.obj %s
+# RUN: yaml2obj < %p/Inputs/guardcf-align-foobar.yaml \
+# RUN: > %T/guardcf-align-foobar.obj
+# RUN: lld-link -out:%T/guardcf-align.exe -entry:main -guard:cf \
+# RUN: %t.obj %T/guardcf-align-foobar.obj
+# RUN: llvm-readobj -coff-load-config %T/guardcf-align.exe | FileCheck %s
+
+# Check that the gfids table contains at least one entry that ends in 0
+# and no entries that end in something other than 0.
+# CHECK: GuardFidTable [
+# CHECK-NOT: 0x{{[0-9A-Fa-f]+[^0]$}}
+# CHECK: 0x{{[0-9A-Fa-f]+0$}}
+# CHECK-NOT: 0x{{[0-9A-Fa-f]+[^0]$}}
+# CHECK: ]
+
+# @feat.00 and _load_config_used to indicate we have gfids.
+ .def @feat.00;
+ .scl 3;
+ .type 0;
+ .endef
+ .globl @feat.00
+@feat.00 = 0x801
+
+ .section .rdata,"dr"
+.globl _load_config_used
+_load_config_used:
+ .long 256
+ .fill 124, 1, 0
+ .quad __guard_fids_table
+ .quad __guard_fids_count
+ .long __guard_flags
+ .fill 128, 1, 0
+
+# Functions that are called indirectly.
+ .section .gfids$y,"dr"
+ .symidx foo
+
+
+ .section .text,"rx"
+ .global main
+main:
+ movq foo, %rcx
+ xorq %rax, %rax
+ callq bar
+ retq
OpenPOWER on IntegriCloud