[lld] r339345 - [COFF] Make the relocation scanning for CFG more discriminating
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 9 06:43:22 PDT 2018
Author: hans
Date: Thu Aug 9 06:43:22 2018
New Revision: 339345
URL: http://llvm.org/viewvc/llvm-project?rev=339345&view=rev
Log:
[COFF] Make the relocation scanning for CFG more discriminating
link.exe ignores REL32 relocations on 32-bit x86, as well as relocations
against non-function symbols such as labels. This makes lld do the same.
Differential Revision: https://reviews.llvm.org/D50430
Added:
lld/trunk/test/COFF/gfids-relocations32.s
lld/trunk/test/COFF/gfids-relocations64.s
Modified:
lld/trunk/COFF/Writer.cpp
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=339345&r1=339344&r2=339345&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Thu Aug 9 06:43:22 2018
@@ -1013,13 +1013,19 @@ static void markSymbolsWithRelocations(O
if (!SC || !SC->isLive())
continue;
- // Look for relocations in this section against symbols in executable output
- // sections.
- for (Symbol *Ref : SC->symbols()) {
- // FIXME: Do further testing to see if the relocation type matters,
- // especially for 32-bit where taking the address of something usually
- // uses an absolute relocation instead of a relative one.
- if (auto *D = dyn_cast_or_null<Defined>(Ref)) {
+ for (const coff_relocation &Reloc : SC->Relocs) {
+ if (Config->Machine == I386 && Reloc.Type == COFF::IMAGE_REL_I386_REL32)
+ // Ignore relative relocations on x86. On x86_64 they can't be ignored
+ // since they're also used to compute absolute addresses.
+ continue;
+
+ Symbol *Ref = SC->File->getSymbol(Reloc.SymbolTableIndex);
+ if (auto *D = dyn_cast_or_null<DefinedCOFF>(Ref)) {
+ if (D->getCOFFSymbol().getComplexType() != COFF::IMAGE_SYM_DTYPE_FUNCTION)
+ // Ignore relocations against non-functions (e.g. labels).
+ continue;
+
+ // Mark the symbol if it's in an executable section.
Chunk *RefChunk = D->getChunk();
OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr;
if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
Added: lld/trunk/test/COFF/gfids-relocations32.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/gfids-relocations32.s?rev=339345&view=auto
==============================================================================
--- lld/trunk/test/COFF/gfids-relocations32.s (added)
+++ lld/trunk/test/COFF/gfids-relocations32.s Thu Aug 9 06:43:22 2018
@@ -0,0 +1,87 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple i686-pc-win32 %s -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -guard:cf -out:%t.exe -entry:main
+# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
+
+# Only f and _main should go in the table.
+# (use /lldmap:map.txt to check their addresses).
+#
+# CHECK: GuardFidTable [
+# CHECK-NEXT: 0x401000
+# CHECK-NEXT: 0x401030
+# CHECK-NEXT: ]
+
+# The input was loosly based on studying this program:
+#
+# void foo() { return; }
+# void bar() { return; }
+# int main() {
+# foo();
+# void (*arr[])() = { &bar };
+# (*arr[0])();
+# return 0;
+# }
+# cl /c a.cc && dumpbin /disasm a.obj > a.txt &&
+# link a.obj /guard:cf /map:map.txt && dumpbin /loadconfig a.exe
+
+
+
+ .def f;
+ .scl 3;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,f
+ .p2align 4
+f: movl $1, %eax
+ ret
+
+
+ .def g;
+ .scl 3;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,g
+ .p2align 4
+g: movl $2, %eax
+ ret
+
+
+ .def label;
+ .scl 6; # StorageClass: Label
+ .type 0; # Type: Not a function.
+ .endef
+ .section .text,"xr",one_only,label
+ .p2align 4
+label: ret
+
+
+ .data
+ .globl fp
+ .p2align 4
+fp: .long f # DIR32 relocation to function
+ .long label # DIR32 relocation to label
+
+
+ .def _main;
+ .scl 2;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,_main
+ .globl _main
+ .p2align 4
+_main: call *fp # DIR32 relocation to data
+ call g # REL32 relocation to function
+ ret
+
+
+# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY32).
+# The linker will define the ___guard_* symbols.
+ .section .rdata,"dr"
+.globl __load_config_used
+__load_config_used:
+ .long 104 # Size.
+ .fill 76, 1, 0
+ .long ___guard_fids_table
+ .long ___guard_fids_count
+ .long ___guard_flags
+ .fill 12, 1, 0
Added: lld/trunk/test/COFF/gfids-relocations64.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/gfids-relocations64.s?rev=339345&view=auto
==============================================================================
--- lld/trunk/test/COFF/gfids-relocations64.s (added)
+++ lld/trunk/test/COFF/gfids-relocations64.s Thu Aug 9 06:43:22 2018
@@ -0,0 +1,76 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple x86_64-pc-win32 %s -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -guard:cf -out:%t.exe -entry:main
+# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK
+
+# f, g, and main go in the table.
+# Including g isn't strictly necessary since it's not an indirect call target,
+# however the linker can't know that because relative relocations are used both
+# for direct calls and for getting the absolute address of a function.
+# (use /lldmap:map.txt to check their addresses).
+#
+# CHECK: GuardFidTable [
+# CHECK-NEXT: 0x140001000
+# CHECK-NEXT: 0x140001010
+# CHECK-NEXT: 0x140001030
+# CHECK-NEXT: ]
+
+ .def f;
+ .scl 3;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,f
+ .p2align 4
+f: movl $1, %eax
+ ret
+
+
+ .def g;
+ .scl 3;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,g
+ .p2align 4
+g: movl $2, %eax
+ ret
+
+
+ .def label;
+ .scl 6; # StorageClass: Label
+ .type 0; # Type: Not a function.
+ .endef
+ .section .text,"xr",one_only,label
+ .p2align 4
+label: ret
+
+
+ .data
+ .globl fp
+ .p2align 4
+fp: .quad f # DIR32 relocation to function
+ .quad label # DIR32 relocation to label
+
+
+ .def main;
+ .scl 2;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,main
+ .globl main
+ .p2align 4
+main: call *fp # DIR32 relocation to data
+ call g # REL32 relocation to function
+ ret
+
+
+# Load configuration directory entry (winnt.h _IMAGE_LOAD_CONFIG_DIRECTORY64).
+# The linker will define the __guard_* symbols.
+ .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
More information about the llvm-commits
mailing list