summaryrefslogtreecommitdiff
path: root/tools/llvm-readobj
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-02-13 20:32:53 +0000
committerReid Kleckner <rnk@google.com>2018-02-13 20:32:53 +0000
commit57d82ee080758dbcea790c879ea68971d6aa6e95 (patch)
tree140f0a308648cd284122ccbc5555054c0ab611d4 /tools/llvm-readobj
parent24775560e220895c25331a17bd8db4d2b6462ed1 (diff)
[LLD] Implement /guard:[no]longjmp
Summary: This protects calls to longjmp from transferring control to arbitrary program points. Instead, longjmp calls are limited to the set of registered setjmp return addresses. This also implements /guard:nolongjmp to allow users to link in object files that call setjmp that weren't compiled with /guard:cf. In this case, the linker will approximate the set of address taken functions, but it will leave longjmp unprotected. I used the following program to test, compiling it with different -guard flags: $ cl -c t.c -guard:cf $ lld-link t.obj -guard:cf #include <setjmp.h> #include <stdio.h> jmp_buf buf; void g() { printf("before longjmp\n"); fflush(stdout); longjmp(buf, 1); } void f() { if (setjmp(buf)) { printf("setjmp returned non-zero\n"); return; } g(); } int main() { f(); printf("hello world\n"); } In particular, the program aborts when the code is compiled *without* -guard:cf and linked with -guard:cf. That indicates that longjmps are protected. Reviewers: ruiu, inglorion, amccarth Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D43217 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325047 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-readobj')
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index a6a2c197741..40334802d8e 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -67,6 +67,8 @@ struct LoadConfigTables {
uint32_t GuardFlags = 0;
uint64_t GuardFidTableVA = 0;
uint64_t GuardFidTableCount = 0;
+ uint64_t GuardLJmpTableVA = 0;
+ uint64_t GuardLJmpTableCount = 0;
};
class COFFDumper : public ObjDumper {
@@ -800,6 +802,11 @@ void COFFDumper::printCOFFLoadConfig() {
printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 4);
}
}
+
+ if (Tables.GuardLJmpTableVA) {
+ ListScope LS(W, "GuardLJmpTable");
+ printRVATable(Tables.GuardLJmpTableVA, Tables.GuardLJmpTableCount, 4);
+ }
}
template <typename T>
@@ -879,6 +886,9 @@ void COFFDumper::printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables) {
W.printHex("GuardRFVerifyStackPointerFunctionPointer",
Conf->GuardRFVerifyStackPointerFunctionPointer);
W.printHex("HotPatchTableOffset", Conf->HotPatchTableOffset);
+
+ Tables.GuardLJmpTableVA = Conf->GuardLongJumpTargetTable;
+ Tables.GuardLJmpTableCount = Conf->GuardLongJumpTargetCount;
}
void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) {