[PATCH] D132901: [LLD] Imply "longjmp" in `/guard:cf`

Alvin Wong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 31 01:05:53 PDT 2022


alvinhochun added a comment.

I did a non-exhaustive test with `clang++ ehcont_guard_msvc.cpp -o ehcont_guard_msvc.exe -target x86_64-pc-windows-msvc -Xclang -ehcontguard -O -Xlinker /guard:xxxxxx`, using MSVC Incremental Linker Version 14.29.30146.0, then checked using `llvm-readobj --coff-load-config ehcont_guard_msvc.exe`.

The result is a bit unexpected:

| link flag                     | guard fid | guard longjmp | guard ehcont |
| ----------------------------- | --------- | ------------- | ------------ |
| (no /guard)                   | no        | no            | no           |
| `/guard:no`                   | no        | no            | no           |
| `/guard:cf`                   | yes       | yes           | no           |
| `/guard:no,cf`                | yes       | yes           | no           |
| `/guard:longjmp`              | yes       | **no**        | no           |
| `/guard:cf,longjmp`           | yes       | yes           | no           |
| `/guard:cf,nolongjmp`         | yes       | no            | no           |
| `/guard:nolongjmp,cf`         | yes       | **yes**       | no           |
| `/guard:ehcont`               | yes       | **no**        | yes          |
| `/guard:cf,ehcont`            | yes       | yes           | yes          |
| `/guard;cf,nolongjmp,ehcont`  | yes       | no            | yes          |
| `/guard:cf,longjmp,ehcont`    | yes       | yes           | yes          |
| `/guard:longjmp,ehcont`       | yes       | **no**        | yes          |
| `/guard:cf,longjmp,ehcont,no` | no        | no            | no           |
| `/guard:no,cf,longjmp,ehcont` | **yes**   | **yes**       | **yes**      |
|



- Options are parsed in order, negation does not override later options.
- `longjmp` does not actually enable guard long jump (might be a bug?)
- `ehguard` does indeed not enable guard long jump.

This is the code I used:

  #include <cstdio>
  #include <setjmp.h>
  
  struct my_exception_t {
      int code;
  };
  
  __attribute__((noinline))
  void do_test(bool should_throw) {
      printf("Starting test, should_throw = %d\n", should_throw);
      try {
          if (should_throw) {
              throw my_exception_t { 1234 };
          }
          puts("Exception not thrown.");
      } catch (my_exception_t ex) {
          printf("Caught exception with value %d.\n", ex.code);
      }
  }
  
  int main(int argc, char *argv[]) {
      if (argc > 1) {
          do_test(true);
      } else {
          do_test(false);
      }
      jmp_buf my_jmp_buf;
      jmp_buf my_jmp_buf2;
      if (setjmp(my_jmp_buf) > 0) {
          puts("Longjmp target reached.");
          return 0;
      }
      puts("Performing longjmp...");
      longjmp(my_jmp_buf2, 1);
      puts("Unexpectedly returned from longjmp!");
      return 0;
  }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D132901/new/

https://reviews.llvm.org/D132901



More information about the llvm-commits mailing list