@@ -437,12 +437,17 @@ export this information, every DSO implements
437
437
438
438
.. code-block :: none
439
439
440
- void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr)
441
-
442
- This function provides external modules with access to CFI checks for the
443
- targets inside this DSO. For each known ``CallSiteTypeId ``, this function
444
- performs an ``llvm.type.test `` with the corresponding type identifier. It
445
- aborts if the type is unknown, or if the check fails.
440
+ void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
441
+
442
+ This function provides external modules with access to CFI checks for
443
+ the targets inside this DSO. For each known ``CallSiteTypeId ``, this
444
+ function performs an ``llvm.type.test `` with the corresponding type
445
+ identifier. It reports an error if the type is unknown, or if the
446
+ check fails. Depending on the values of compiler flags
447
+ ``-fsanitize-trap `` and ``-fsanitize-recover ``, this function may
448
+ print an error, abort and/or return to the caller. ``DiagData `` is an
449
+ opaque pointer to the diagnostic information about the error, or
450
+ ``null `` if the caller does not provide this information.
446
451
447
452
The basic implementation is a large switch statement over all values
448
453
of CallSiteTypeId supported by this DSO, and each case is similar to
@@ -452,11 +457,10 @@ CFI Shadow
452
457
----------
453
458
454
459
To route CFI checks to the target DSO's __cfi_check function, a
455
- mapping from possible virtual / indirect call targets to
456
- the corresponding __cfi_check functions is maintained. This mapping is
460
+ mapping from possible virtual / indirect call targets to the
461
+ corresponding __cfi_check functions is maintained. This mapping is
457
462
implemented as a sparse array of 2 bytes for every possible page (4096
458
- bytes) of memory. The table is kept readonly (FIXME: not yet) most of
459
- the time.
463
+ bytes) of memory. The table is kept readonly most of the time.
460
464
461
465
There are 3 types of shadow values:
462
466
@@ -481,14 +485,24 @@ them.
481
485
CFI_SlowPath
482
486
------------
483
487
484
- The slow path check is implemented in compiler-rt library as
488
+ The slow path check is implemented in a runtime support library as
485
489
486
490
.. code-block :: none
487
491
488
492
void __cfi_slowpath(uint64 CallSiteTypeId, void *TargetAddr)
489
-
490
- This functions loads a shadow value for ``TargetAddr ``, finds the
491
- address of __cfi_check as described above and calls that.
493
+ void __cfi_slowpath_diag(uint64 CallSiteTypeId, void *TargetAddr, void *DiagData)
494
+
495
+ These functions loads a shadow value for ``TargetAddr ``, finds the
496
+ address of ``__cfi_check `` as described above and calls
497
+ that. ``DiagData `` is an opaque pointer to diagnostic data which is
498
+ passed verbatim to ``__cfi_check ``, and ``__cfi_slowpath `` passes
499
+ ``nullptr `` instead.
500
+
501
+ Compiler-RT library contains reference implementations of slowpath
502
+ functions, but they have unresolvable issues with correctness and
503
+ performance in the handling of dlopen(). It is recommended that
504
+ platforms provide their own implementations, usually as part of libc
505
+ or libdl.
492
506
493
507
Position-independent executable requirement
494
508
-------------------------------------------
0 commit comments