forked from OSchip/llvm-project
[dfsan] Add full fast8 support
Complete support for fast8: - amend shadow size and mapping in runtime - remove fast16 mode and -dfsan-fast-16-labels flag - remove legacy mode and make fast8 mode the default - remove dfsan-fast-8-labels flag - remove functions in dfsan interface only applicable to legacy - remove legacy-related instrumentation code and tests - update documentation. Reviewed By: stephan.yichao.zhao, browneee Differential Revision: https://reviews.llvm.org/D103745
This commit is contained in:
parent
3b69318eef
commit
5b4dda550e
|
@ -140,59 +140,14 @@ For example:
|
|||
Example
|
||||
=======
|
||||
|
||||
DataFlowSanitizer supports up to 8 labels, to achieve low CPU and code
|
||||
size overhead. Base labels are simply 8-bit unsigned integers that are
|
||||
powers of 2 (i.e. 1, 2, 4, 8, ..., 128), and union labels are created
|
||||
by ORing base labels.
|
||||
|
||||
The following program demonstrates label propagation by checking that
|
||||
the correct labels are propagated.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <sanitizer/dfsan_interface.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void) {
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
int j = 2;
|
||||
dfsan_label j_label = dfsan_create_label("j", 0);
|
||||
dfsan_set_label(j_label, &j, sizeof(j));
|
||||
|
||||
int k = 3;
|
||||
dfsan_label k_label = dfsan_create_label("k", 0);
|
||||
dfsan_set_label(k_label, &k, sizeof(k));
|
||||
|
||||
dfsan_label ij_label = dfsan_get_label(i + j);
|
||||
assert(dfsan_has_label(ij_label, i_label));
|
||||
assert(dfsan_has_label(ij_label, j_label));
|
||||
assert(!dfsan_has_label(ij_label, k_label));
|
||||
|
||||
dfsan_label ijk_label = dfsan_get_label(i + j + k);
|
||||
assert(dfsan_has_label(ijk_label, i_label));
|
||||
assert(dfsan_has_label(ijk_label, j_label));
|
||||
assert(dfsan_has_label(ijk_label, k_label));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fast16labels mode
|
||||
=================
|
||||
|
||||
If you need 16 or fewer labels, you can use fast16labels instrumentation for
|
||||
less CPU and code size overhead. To use fast16labels instrumentation, you'll
|
||||
need to specify `-fsanitize=dataflow -mllvm -dfsan-fast-16-labels` in your
|
||||
compile and link commands and use a modified API for creating and managing
|
||||
labels.
|
||||
|
||||
In fast16labels mode, base labels are simply 16-bit unsigned integers that are
|
||||
powers of 2 (i.e. 1, 2, 4, 8, ..., 32768), and union labels are created by ORing
|
||||
base labels. In this mode DFSan does not manage any label metadata, so the
|
||||
functions `dfsan_create_label`, `dfsan_union`, `dfsan_get_label_info`,
|
||||
`dfsan_has_label`, `dfsan_has_label_with_desc`, `dfsan_get_label_count`, and
|
||||
`dfsan_dump_labels` are unsupported. Instead of using them, the user should
|
||||
maintain any necessary metadata about base labels themselves.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <sanitizer/dfsan_interface.h>
|
||||
|
@ -216,6 +171,11 @@ For example:
|
|||
assert(!(ij_label & k_label)); // ij_label doesn't have k_label
|
||||
assert(ij_label == 3); // Verifies all of the above
|
||||
|
||||
// Or, equivalently:
|
||||
assert(dfsan_has_label(ij_label, i_label));
|
||||
assert(dfsan_has_label(ij_label, j_label));
|
||||
assert(!dfsan_has_label(ij_label, k_label));
|
||||
|
||||
dfsan_label ijk_label = dfsan_get_label(i + j + k);
|
||||
|
||||
assert(ijk_label & i_label); // ijk_label has i_label
|
||||
|
@ -223,6 +183,11 @@ For example:
|
|||
assert(ijk_label & k_label); // ijk_label has k_label
|
||||
assert(ijk_label == 7); // Verifies all of the above
|
||||
|
||||
// Or, equivalently:
|
||||
assert(dfsan_has_label(ijk_label, i_label));
|
||||
assert(dfsan_has_label(ijk_label, j_label));
|
||||
assert(dfsan_has_label(ijk_label, k_label));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,7 @@ DataFlowSanitizer is a program instrumentation which can associate
|
|||
a number of taint labels with any data stored in any memory region
|
||||
accessible by the program. The analysis is dynamic, which means that
|
||||
it operates on a running program, and tracks how the labels propagate
|
||||
through that program. The tool shall support a large (>100) number
|
||||
of labels, such that programs which operate on large numbers of data
|
||||
items may be analysed with each data item being tracked separately.
|
||||
through that program.
|
||||
|
||||
Use Cases
|
||||
---------
|
||||
|
@ -28,16 +26,13 @@ ensure it isn't exiting the program anywhere it shouldn't be.
|
|||
Interface
|
||||
---------
|
||||
|
||||
A number of functions are provided which will create taint labels,
|
||||
attach labels to memory regions and extract the set of labels
|
||||
associated with a specific memory region. These functions are declared
|
||||
in the header file ``sanitizer/dfsan_interface.h``.
|
||||
A number of functions are provided which will attach taint labels to
|
||||
memory regions and extract the set of labels associated with a
|
||||
specific memory region. These functions are declared in the header
|
||||
file ``sanitizer/dfsan_interface.h``.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/// Creates and returns a base label with the given description and user data.
|
||||
dfsan_label dfsan_create_label(const char *desc, void *userdata);
|
||||
|
||||
/// Sets the label for each address in [addr,addr+size) to \c label.
|
||||
void dfsan_set_label(dfsan_label label, void *addr, size_t size);
|
||||
|
||||
|
@ -53,93 +48,57 @@ in the header file ``sanitizer/dfsan_interface.h``.
|
|||
/// value.
|
||||
dfsan_label dfsan_get_label(long data);
|
||||
|
||||
/// Retrieves a pointer to the dfsan_label_info struct for the given label.
|
||||
const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label);
|
||||
|
||||
/// Returns whether the given label label contains the label elem.
|
||||
int dfsan_has_label(dfsan_label label, dfsan_label elem);
|
||||
|
||||
/// If the given label label contains a label with the description desc, returns
|
||||
/// that label, else returns 0.
|
||||
dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
|
||||
/// Computes the union of \c l1 and \c l2, resulting in a union label.
|
||||
dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
|
||||
|
||||
Taint label representation
|
||||
--------------------------
|
||||
|
||||
As stated above, the tool must track a large number of taint
|
||||
labels. This poses an implementation challenge, as most multiple-label
|
||||
tainting systems assign one label per bit to shadow storage, and
|
||||
union taint labels using a bitwise or operation. This will not scale
|
||||
to clients which use hundreds or thousands of taint labels, as the
|
||||
label union operation becomes O(n) in the number of supported labels,
|
||||
and data associated with it will quickly dominate the live variable
|
||||
set, causing register spills and hampering performance.
|
||||
We use an 8-bit unsigned integer for the representation of a
|
||||
label. The label identifier 0 is special, and means that the data item
|
||||
is unlabelled. This is optimizing for low CPU and code size overhead
|
||||
of the instrumentation. When a label union operation is requested at a
|
||||
join point (any arithmetic or logical operation with two or more
|
||||
operands, such as addition), we can simply OR the two labels in O(1).
|
||||
|
||||
Instead, a low overhead approach is proposed which is best-case O(log\
|
||||
:sub:`2` n) during execution. The underlying assumption is that
|
||||
the required space of label unions is sparse, which is a reasonable
|
||||
assumption to make given that we are optimizing for the case where
|
||||
applications mostly copy data from one place to another, without often
|
||||
invoking the need for an actual union operation. The representation
|
||||
of a taint label is a 16-bit integer, and new labels are allocated
|
||||
sequentially from a pool. The label identifier 0 is special, and means
|
||||
that the data item is unlabelled.
|
||||
|
||||
When a label union operation is requested at a join point (any
|
||||
arithmetic or logical operation with two or more operands, such as
|
||||
addition), the code checks whether a union is required, whether the
|
||||
same union has been requested before, and whether one union label
|
||||
subsumes the other. If so, it returns the previously allocated union
|
||||
label. If not, it allocates a new union label from the same pool used
|
||||
for new labels.
|
||||
|
||||
Specifically, the instrumentation pass will insert code like this
|
||||
to decide the union label ``lu`` for a pair of labels ``l1``
|
||||
and ``l2``:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
if (l1 == l2)
|
||||
lu = l1;
|
||||
else
|
||||
lu = __dfsan_union(l1, l2);
|
||||
|
||||
The equality comparison is outlined, to provide an early exit in
|
||||
the common cases where the program is processing unlabelled data, or
|
||||
where the two data items have the same label. ``__dfsan_union`` is
|
||||
a runtime library function which performs all other union computation.
|
||||
|
||||
Further optimizations are possible, for example if ``l1`` is known
|
||||
at compile time to be zero (e.g. it is derived from a constant),
|
||||
``l2`` can be used for ``lu``, and vice versa.
|
||||
Users are responsible for managing the 8 integer labels (i.e., keeping
|
||||
track of what labels they have used so far, picking one that is yet
|
||||
unused, etc).
|
||||
|
||||
Memory layout and label management
|
||||
----------------------------------
|
||||
|
||||
The following is the current memory layout for Linux/x86\_64:
|
||||
The following is the memory layout for Linux/x86\_64:
|
||||
|
||||
+---------------+---------------+--------------------+
|
||||
| Start | End | Use |
|
||||
+===============+===============+====================+
|
||||
| 0x700000008000|0x800000000000 | application memory |
|
||||
+---------------+---------------+--------------------+
|
||||
| 0x200200000000|0x700000008000 | unused |
|
||||
| 0x300000000000|0x700000008000 | unused |
|
||||
+---------------+---------------+--------------------+
|
||||
| 0x200000000000|0x200200000000 | union table |
|
||||
| 0x200000008000|0x300000000000 | origin |
|
||||
+---------------+---------------+--------------------+
|
||||
| 0x000000010000|0x200000000000 | shadow memory |
|
||||
| 0x200000000000|0x200000008000 | unused |
|
||||
+---------------+---------------+--------------------+
|
||||
| 0x100000008000|0x200000000000 | shadow memory |
|
||||
+---------------+---------------+--------------------+
|
||||
| 0x000000010000|0x100000008000 | unused |
|
||||
+---------------+---------------+--------------------+
|
||||
| 0x000000000000|0x000000010000 | reserved by kernel |
|
||||
+---------------+---------------+--------------------+
|
||||
|
||||
Each byte of application memory corresponds to two bytes of shadow
|
||||
memory, which are used to store its taint label. As for LLVM SSA
|
||||
Each byte of application memory corresponds to a single byte of shadow
|
||||
memory, which is used to store its taint label. As for LLVM SSA
|
||||
registers, we have not found it necessary to associate a label with
|
||||
each byte or bit of data, as some other tools do. Instead, labels are
|
||||
associated directly with registers. Loads will result in a union of
|
||||
all shadow labels corresponding to bytes loaded (which most of the
|
||||
time will be short circuited by the initial comparison) and stores will
|
||||
result in a copy of the label to the shadow of all bytes stored to.
|
||||
all shadow labels corresponding to bytes loaded, and stores will
|
||||
result in a copy of the label of the stored value to the shadow of all
|
||||
bytes stored to.
|
||||
|
||||
Propagating labels through arguments
|
||||
------------------------------------
|
||||
|
|
|
@ -21,34 +21,15 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint16_t dfsan_label;
|
||||
typedef uint8_t dfsan_label;
|
||||
typedef uint32_t dfsan_origin;
|
||||
|
||||
/// Stores information associated with a specific label identifier. A label
|
||||
/// may be a base label created using dfsan_create_label, with associated
|
||||
/// text description and user data, or an automatically created union label,
|
||||
/// which represents the union of two label identifiers (which may themselves
|
||||
/// be base or union labels).
|
||||
struct dfsan_label_info {
|
||||
// Fields for union labels, set to 0 for base labels.
|
||||
dfsan_label l1;
|
||||
dfsan_label l2;
|
||||
|
||||
// Fields for base labels.
|
||||
const char *desc;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
/// Signature of the callback argument to dfsan_set_write_callback().
|
||||
typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count);
|
||||
|
||||
/// Computes the union of \c l1 and \c l2, possibly creating a union label in
|
||||
/// the process.
|
||||
/// Computes the union of \c l1 and \c l2, resulting in a union label.
|
||||
dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
|
||||
|
||||
/// Creates and returns a base label with the given description and user data.
|
||||
dfsan_label dfsan_create_label(const char *desc, void *userdata);
|
||||
|
||||
/// Sets the label for each address in [addr,addr+size) to \c label.
|
||||
void dfsan_set_label(dfsan_label label, void *addr, size_t size);
|
||||
|
||||
|
@ -73,19 +54,9 @@ dfsan_origin dfsan_get_origin(long data);
|
|||
/// Retrieves the label associated with the data at the given address.
|
||||
dfsan_label dfsan_read_label(const void *addr, size_t size);
|
||||
|
||||
/// Retrieves a pointer to the dfsan_label_info struct for the given label.
|
||||
const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label);
|
||||
|
||||
/// Returns whether the given label label contains the label elem.
|
||||
int dfsan_has_label(dfsan_label label, dfsan_label elem);
|
||||
|
||||
/// If the given label label contains a label with the description desc, returns
|
||||
/// that label, else returns 0.
|
||||
dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
|
||||
|
||||
/// Returns the number of labels allocated.
|
||||
size_t dfsan_get_label_count(void);
|
||||
|
||||
/// Flushes the DFSan shadow, i.e. forgets about all labels currently associated
|
||||
/// with the application memory. Use this call to start over the taint tracking
|
||||
/// within the same process.
|
||||
|
@ -99,12 +70,6 @@ void dfsan_flush(void);
|
|||
/// callback executes. Pass in NULL to remove any callback.
|
||||
void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback);
|
||||
|
||||
/// Writes the labels currently used by the program to the given file
|
||||
/// descriptor. The lines of the output have the following format:
|
||||
///
|
||||
/// <label> <parent label 1> <parent label 2> <label description if any>
|
||||
void dfsan_dump_labels(int fd);
|
||||
|
||||
/// Interceptor hooks.
|
||||
/// Whenever a dfsan's custom function is called the corresponding
|
||||
/// hook is called it non-zero. The hooks should be defined by the user.
|
||||
|
|
|
@ -36,14 +36,6 @@
|
|||
|
||||
using namespace __dfsan;
|
||||
|
||||
typedef atomic_uint16_t atomic_dfsan_label;
|
||||
static const dfsan_label kInitializingLabel = -1;
|
||||
|
||||
static const uptr kNumLabels = 1 << (sizeof(dfsan_label) * 8);
|
||||
|
||||
static atomic_dfsan_label __dfsan_last_label;
|
||||
static dfsan_label_info __dfsan_label_info[kNumLabels];
|
||||
|
||||
Flags __dfsan::flags_data;
|
||||
|
||||
// The size of TLS variables. These constants must be kept in sync with the ones
|
||||
|
@ -80,22 +72,22 @@ int __dfsan_get_track_origins() {
|
|||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x300200000000 (kUnusedAddr)
|
||||
// | union table |
|
||||
// +--------------------+ 0x300000000000 (kUnionTableAddr)
|
||||
// +--------------------+ 0x300000000000 (kUnusedAddr)
|
||||
// | origin |
|
||||
// +--------------------+ 0x200000000000 (kOriginAddr)
|
||||
// +--------------------+ 0x200000008000 (kOriginAddr)
|
||||
// | unused |
|
||||
// +--------------------+ 0x200000000000
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x000000010000 (kShadowAddr)
|
||||
// +--------------------+ 0x100000008000 (kShadowAddr)
|
||||
// | unused |
|
||||
// +--------------------+ 0x000000010000
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x000000000000
|
||||
//
|
||||
// To derive a shadow memory address from an application memory address,
|
||||
// bits 44-46 are cleared to bring the address into the range
|
||||
// [0x000000008000,0x100000000000). Then the address is shifted left by 1 to
|
||||
// account for the double byte representation of shadow labels and move the
|
||||
// address into the shadow memory range. See the function shadow_for below.
|
||||
|
||||
// To derive a shadow memory address from an application memory address, bits
|
||||
// 45-46 are cleared to bring the address into the range
|
||||
// [0x100000008000,0x200000000000). See the function shadow_for below.
|
||||
//
|
||||
// On Linux/MIPS64, memory is laid out as follows:
|
||||
//
|
||||
// +--------------------+ 0x10000000000 (top of memory)
|
||||
|
@ -104,11 +96,11 @@ int __dfsan_get_track_origins() {
|
|||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x2200000000 (kUnusedAddr)
|
||||
// | union table |
|
||||
// +--------------------+ 0x2000000000 (kUnionTableAddr)
|
||||
// +--------------------+ 0x2000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// +--------------------+ 0x1000008000 (kShadowAddr)
|
||||
// | unused |
|
||||
// +--------------------+ 0x0000010000
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x0000000000
|
||||
|
||||
|
@ -120,9 +112,7 @@ int __dfsan_get_track_origins() {
|
|||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x1200000000 (kUnusedAddr)
|
||||
// | union table |
|
||||
// +--------------------+ 0x1000000000 (kUnionTableAddr)
|
||||
// +--------------------+ 0x1000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// | reserved by kernel |
|
||||
|
@ -136,9 +126,7 @@ int __dfsan_get_track_origins() {
|
|||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x1200000000 (kUnusedAddr)
|
||||
// | union table |
|
||||
// +--------------------+ 0x8000000000 (kUnionTableAddr)
|
||||
// +--------------------+ 0x8000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// | reserved by kernel |
|
||||
|
@ -156,102 +144,19 @@ int __dfsan_get_track_origins() {
|
|||
// | |
|
||||
// | unused |
|
||||
// | |
|
||||
// +--------------------+ 0x1200000000 (kUnusedAddr)
|
||||
// | union table |
|
||||
// +--------------------+ 0x8000000000 (kUnionTableAddr)
|
||||
// +--------------------+ 0x8000000000 (kUnusedAddr)
|
||||
// | shadow memory |
|
||||
// +--------------------+ 0x0000010000 (kShadowAddr)
|
||||
// | reserved by kernel |
|
||||
// +--------------------+ 0x0000000000
|
||||
|
||||
typedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels];
|
||||
|
||||
#ifdef DFSAN_RUNTIME_VMA
|
||||
// Runtime detected VMA size.
|
||||
int __dfsan::vmaSize;
|
||||
#endif
|
||||
|
||||
static uptr UnusedAddr() {
|
||||
return UnionTableAddr() + sizeof(dfsan_union_table_t);
|
||||
}
|
||||
|
||||
static atomic_dfsan_label *union_table(dfsan_label l1, dfsan_label l2) {
|
||||
return &(*(dfsan_union_table_t *) UnionTableAddr())[l1][l2];
|
||||
}
|
||||
|
||||
// Checks we do not run out of labels.
|
||||
static void dfsan_check_label(dfsan_label label) {
|
||||
if (label == kInitializingLabel) {
|
||||
Report("FATAL: DataFlowSanitizer: out of labels\n");
|
||||
Die();
|
||||
}
|
||||
}
|
||||
|
||||
// Resolves the union of two unequal labels. Nonequality is a precondition for
|
||||
// this function (the instrumentation pass inlines the equality test).
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
dfsan_label __dfsan_union(dfsan_label l1, dfsan_label l2) {
|
||||
DCHECK_NE(l1, l2);
|
||||
|
||||
if (l1 == 0)
|
||||
return l2;
|
||||
if (l2 == 0)
|
||||
return l1;
|
||||
|
||||
// If no labels have been created, yet l1 and l2 are non-zero, we are using
|
||||
// fast16labels mode.
|
||||
if (atomic_load(&__dfsan_last_label, memory_order_relaxed) == 0)
|
||||
return l1 | l2;
|
||||
|
||||
if (l1 > l2)
|
||||
Swap(l1, l2);
|
||||
|
||||
atomic_dfsan_label *table_ent = union_table(l1, l2);
|
||||
// We need to deal with the case where two threads concurrently request
|
||||
// a union of the same pair of labels. If the table entry is uninitialized,
|
||||
// (i.e. 0) use a compare-exchange to set the entry to kInitializingLabel
|
||||
// (i.e. -1) to mark that we are initializing it.
|
||||
dfsan_label label = 0;
|
||||
if (atomic_compare_exchange_strong(table_ent, &label, kInitializingLabel,
|
||||
memory_order_acquire)) {
|
||||
// Check whether l2 subsumes l1. We don't need to check whether l1
|
||||
// subsumes l2 because we are guaranteed here that l1 < l2, and (at least
|
||||
// in the cases we are interested in) a label may only subsume labels
|
||||
// created earlier (i.e. with a lower numerical value).
|
||||
if (__dfsan_label_info[l2].l1 == l1 ||
|
||||
__dfsan_label_info[l2].l2 == l1) {
|
||||
label = l2;
|
||||
} else {
|
||||
label =
|
||||
atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1;
|
||||
dfsan_check_label(label);
|
||||
__dfsan_label_info[label].l1 = l1;
|
||||
__dfsan_label_info[label].l2 = l2;
|
||||
}
|
||||
atomic_store(table_ent, label, memory_order_release);
|
||||
} else if (label == kInitializingLabel) {
|
||||
// Another thread is initializing the entry. Wait until it is finished.
|
||||
do {
|
||||
internal_sched_yield();
|
||||
label = atomic_load(table_ent, memory_order_acquire);
|
||||
} while (label == kInitializingLabel);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
dfsan_label __dfsan_union_load(const dfsan_label *ls, uptr n) {
|
||||
dfsan_label label = ls[0];
|
||||
for (uptr i = 1; i != n; ++i) {
|
||||
dfsan_label next_label = ls[i];
|
||||
if (label != next_label)
|
||||
label = __dfsan_union(label, next_label);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
dfsan_label __dfsan_union_load_fast16labels(const dfsan_label *ls, uptr n) {
|
||||
dfsan_label label = ls[0];
|
||||
for (uptr i = 1; i != n; ++i)
|
||||
label |= ls[i];
|
||||
|
@ -301,24 +206,10 @@ __dfsan_vararg_wrapper(const char *fname) {
|
|||
Die();
|
||||
}
|
||||
|
||||
// Like __dfsan_union, but for use from the client or custom functions. Hence
|
||||
// the equality comparison is done here before calling __dfsan_union.
|
||||
// Resolves the union of two labels.
|
||||
SANITIZER_INTERFACE_ATTRIBUTE dfsan_label
|
||||
dfsan_union(dfsan_label l1, dfsan_label l2) {
|
||||
if (l1 == l2)
|
||||
return l1;
|
||||
return __dfsan_union(l1, l2);
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
dfsan_label dfsan_create_label(const char *desc, void *userdata) {
|
||||
dfsan_label label =
|
||||
atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1;
|
||||
dfsan_check_label(label);
|
||||
__dfsan_label_info[label].l1 = __dfsan_label_info[label].l2 = 0;
|
||||
__dfsan_label_info[label].desc = desc;
|
||||
__dfsan_label_info[label].userdata = userdata;
|
||||
return label;
|
||||
return l1 | l2;
|
||||
}
|
||||
|
||||
// Return the origin of the first taint byte in the size bytes from the address
|
||||
|
@ -429,7 +320,7 @@ static void CopyOrigin(const void *dst, const void *src, uptr size,
|
|||
// Align src up.
|
||||
uptr s = AlignUp((uptr)src);
|
||||
dfsan_origin *src_o = (dfsan_origin *)origin_for((void *)s);
|
||||
u64 *src_s = (u64 *)shadow_for((void *)s);
|
||||
u32 *src_s = (u32 *)shadow_for((void *)s);
|
||||
dfsan_origin *src_end = (dfsan_origin *)origin_for((void *)(s + (end - beg)));
|
||||
dfsan_origin *dst_o = (dfsan_origin *)origin_for((void *)beg);
|
||||
dfsan_origin last_src_o = 0;
|
||||
|
@ -465,7 +356,7 @@ static void ReverseCopyOrigin(const void *dst, const void *src, uptr size,
|
|||
uptr s = AlignUp((uptr)src);
|
||||
dfsan_origin *src =
|
||||
(dfsan_origin *)origin_for((void *)(s + end - beg - kOriginAlign));
|
||||
u64 *src_s = (u64 *)shadow_for((void *)(s + end - beg - kOriginAlign));
|
||||
u32 *src_s = (u32 *)shadow_for((void *)(s + end - beg - kOriginAlign));
|
||||
dfsan_origin *src_begin = (dfsan_origin *)origin_for((void *)s);
|
||||
dfsan_origin *dst =
|
||||
(dfsan_origin *)origin_for((void *)(end - kOriginAlign));
|
||||
|
@ -628,7 +519,7 @@ void dfsan_copy_memory(void *dst, const void *src, uptr size) {
|
|||
// origin chain with the previous ID o and the current stack trace. This is
|
||||
// used by instrumentation to reduce code size when too much code is inserted.
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_maybe_store_origin(
|
||||
u16 s, void *p, uptr size, dfsan_origin o) {
|
||||
dfsan_label s, void *p, uptr size, dfsan_origin o) {
|
||||
if (UNLIKELY(s)) {
|
||||
GET_CALLER_PC_BP_SP;
|
||||
(void)sp;
|
||||
|
@ -726,8 +617,7 @@ void dfsan_add_label(dfsan_label label, void *addr, uptr size) {
|
|||
}
|
||||
|
||||
for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp)
|
||||
if (*labelp != label)
|
||||
*labelp = __dfsan_union(*labelp, label);
|
||||
*labelp |= label;
|
||||
}
|
||||
|
||||
// Unlike the other dfsan interface functions the behavior of this function
|
||||
|
@ -783,57 +673,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void dfsan_set_label_origin(dfsan_label label,
|
|||
__dfsan_set_label(label, origin, addr, size);
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
||||
const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label) {
|
||||
return &__dfsan_label_info[label];
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE int
|
||||
dfsan_has_label(dfsan_label label, dfsan_label elem) {
|
||||
if (label == elem)
|
||||
return true;
|
||||
const dfsan_label_info *info = dfsan_get_label_info(label);
|
||||
if (info->l1 != 0) {
|
||||
return dfsan_has_label(info->l1, elem) || dfsan_has_label(info->l2, elem);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label
|
||||
dfsan_has_label_with_desc(dfsan_label label, const char *desc) {
|
||||
const dfsan_label_info *info = dfsan_get_label_info(label);
|
||||
if (info->l1 != 0) {
|
||||
return dfsan_has_label_with_desc(info->l1, desc) ||
|
||||
dfsan_has_label_with_desc(info->l2, desc);
|
||||
} else {
|
||||
return internal_strcmp(desc, info->desc) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr
|
||||
dfsan_get_label_count(void) {
|
||||
dfsan_label max_label_allocated =
|
||||
atomic_load(&__dfsan_last_label, memory_order_relaxed);
|
||||
|
||||
return static_cast<uptr>(max_label_allocated);
|
||||
}
|
||||
|
||||
extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
|
||||
dfsan_dump_labels(int fd) {
|
||||
dfsan_label last_label =
|
||||
atomic_load(&__dfsan_last_label, memory_order_relaxed);
|
||||
for (uptr l = 1; l <= last_label; ++l) {
|
||||
char buf[64];
|
||||
internal_snprintf(buf, sizeof(buf), "%u %u %u ", l,
|
||||
__dfsan_label_info[l].l1, __dfsan_label_info[l].l2);
|
||||
WriteToFile(fd, buf, internal_strlen(buf));
|
||||
if (__dfsan_label_info[l].l1 == 0 && __dfsan_label_info[l].desc) {
|
||||
WriteToFile(fd, __dfsan_label_info[l].desc,
|
||||
internal_strlen(__dfsan_label_info[l].desc));
|
||||
}
|
||||
WriteToFile(fd, "\n", 1);
|
||||
}
|
||||
return (label & elem) == elem;
|
||||
}
|
||||
|
||||
class Decorator : public __sanitizer::SanitizerCommonDecorator {
|
||||
|
@ -1068,22 +910,6 @@ static void InitializePlatformEarly() {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void dfsan_fini() {
|
||||
if (internal_strcmp(flags().dump_labels_at_exit, "") != 0) {
|
||||
fd_t fd = OpenFile(flags().dump_labels_at_exit, WrOnly);
|
||||
if (fd == kInvalidFd) {
|
||||
Report("WARNING: DataFlowSanitizer: unable to open output file %s\n",
|
||||
flags().dump_labels_at_exit);
|
||||
return;
|
||||
}
|
||||
|
||||
Report("INFO: DataFlowSanitizer: dumping labels to %s\n",
|
||||
flags().dump_labels_at_exit);
|
||||
dfsan_dump_labels(fd);
|
||||
CloseFile(fd);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void dfsan_flush() {
|
||||
if (!MmapFixedSuperNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr()))
|
||||
Die();
|
||||
|
@ -1115,11 +941,6 @@ static void DFsanInit(int argc, char **argv, char **envp) {
|
|||
|
||||
initialize_interceptors();
|
||||
|
||||
// Register the fini callback to run when the program terminates successfully
|
||||
// or it is killed by the runtime.
|
||||
Atexit(dfsan_fini);
|
||||
AddDieCallback(dfsan_fini);
|
||||
|
||||
// Set up threads
|
||||
DFsanTSDInit(DFsanTSDDtor);
|
||||
|
||||
|
@ -1129,8 +950,6 @@ static void DFsanInit(int argc, char **argv, char **envp) {
|
|||
SetCurrentThread(main_thread);
|
||||
main_thread->ThreadStart();
|
||||
|
||||
__dfsan_label_info[kInitializingLabel].desc = "<init label>";
|
||||
|
||||
dfsan_init_is_running = false;
|
||||
dfsan_inited = true;
|
||||
}
|
||||
|
|
|
@ -18,21 +18,14 @@
|
|||
|
||||
#include "dfsan_platform.h"
|
||||
|
||||
using __sanitizer::u16;
|
||||
using __sanitizer::u32;
|
||||
using __sanitizer::u8;
|
||||
using __sanitizer::uptr;
|
||||
|
||||
// Copy declarations from public sanitizer/dfsan_interface.h header here.
|
||||
typedef u16 dfsan_label;
|
||||
typedef u8 dfsan_label;
|
||||
typedef u32 dfsan_origin;
|
||||
|
||||
struct dfsan_label_info {
|
||||
dfsan_label l1;
|
||||
dfsan_label l2;
|
||||
const char *desc;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
void dfsan_add_label(dfsan_label label, void *addr, uptr size);
|
||||
void dfsan_set_label(dfsan_label label, void *addr, uptr size);
|
||||
|
@ -68,7 +61,7 @@ extern bool dfsan_init_is_running;
|
|||
void initialize_interceptors();
|
||||
|
||||
inline dfsan_label *shadow_for(void *ptr) {
|
||||
return (dfsan_label *) ((((uptr) ptr) & ShadowMask()) << 1);
|
||||
return (dfsan_label *)(((uptr)ptr) & ShadowMask());
|
||||
}
|
||||
|
||||
inline const dfsan_label *shadow_for(const void *ptr) {
|
||||
|
@ -76,7 +69,7 @@ inline const dfsan_label *shadow_for(const void *ptr) {
|
|||
}
|
||||
|
||||
inline uptr unaligned_origin_for(uptr ptr) {
|
||||
return OriginAddr() + (ptr & ShadowMask());
|
||||
return OriginAddr() - ShadowAddr() + (ptr & ShadowMask());
|
||||
}
|
||||
|
||||
inline dfsan_origin *origin_for(void *ptr) {
|
||||
|
@ -98,6 +91,15 @@ inline bool has_valid_shadow_addr(const void *ptr) {
|
|||
return is_shadow_addr_valid((uptr)ptr_s);
|
||||
}
|
||||
|
||||
inline bool is_origin_addr_valid(uptr origin_addr) {
|
||||
return (uptr)origin_addr >= OriginAddr() && (uptr)origin_addr < UnusedAddr();
|
||||
}
|
||||
|
||||
inline bool has_valid_origin_addr(const void *ptr) {
|
||||
const dfsan_origin *ptr_orig = origin_for(ptr);
|
||||
return is_origin_addr_valid((uptr)ptr_orig);
|
||||
}
|
||||
|
||||
void dfsan_copy_memory(void *dst, const void *src, uptr size);
|
||||
|
||||
void dfsan_allocator_init();
|
||||
|
|
|
@ -26,9 +26,6 @@ DFSAN_FLAG(
|
|||
"(e.g., when comparing strings, ignore the fact that the output of the"
|
||||
"comparison might be data-dependent on the content of the strings). This"
|
||||
"applies only to the custom functions defined in 'custom.c'.")
|
||||
DFSAN_FLAG(const char *, dump_labels_at_exit, "", "The path of the file where "
|
||||
"to dump the labels when the "
|
||||
"program terminates.")
|
||||
DFSAN_FLAG(
|
||||
int, origin_history_size, Origin::kMaxDepth,
|
||||
"The limit of origin chain length. Non-positive values mean unlimited.")
|
||||
|
|
|
@ -14,41 +14,45 @@
|
|||
#ifndef DFSAN_PLATFORM_H
|
||||
#define DFSAN_PLATFORM_H
|
||||
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
|
||||
namespace __dfsan {
|
||||
|
||||
using __sanitizer::uptr;
|
||||
|
||||
#if defined(__x86_64__)
|
||||
struct Mapping {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kOriginAddr = 0x200000000000;
|
||||
static const uptr kUnionTableAddr = 0x300000000000;
|
||||
static const uptr kShadowAddr = 0x100000008000;
|
||||
static const uptr kOriginAddr = 0x200000008000;
|
||||
static const uptr kUnusedAddr = 0x300000000000;
|
||||
static const uptr kAppAddr = 0x700000008000;
|
||||
static const uptr kShadowMask = ~0x700000000000;
|
||||
static const uptr kShadowMask = ~0x600000000000;
|
||||
};
|
||||
#elif defined(__mips64)
|
||||
struct Mapping {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnionTableAddr = 0x2000000000;
|
||||
static const uptr kShadowAddr = 0x1000008000;
|
||||
static const uptr kUnusedAddr = 0x2000000000;
|
||||
static const uptr kAppAddr = 0xF000008000;
|
||||
static const uptr kShadowMask = ~0xF000000000;
|
||||
static const uptr kShadowMask = ~0xE000000000;
|
||||
};
|
||||
#elif defined(__aarch64__)
|
||||
struct Mapping39 {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnionTableAddr = 0x1000000000;
|
||||
static const uptr kUnusedAddr = 0x1000000000;
|
||||
static const uptr kAppAddr = 0x7000008000;
|
||||
static const uptr kShadowMask = ~0x7800000000;
|
||||
};
|
||||
|
||||
struct Mapping42 {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnionTableAddr = 0x8000000000;
|
||||
static const uptr kUnusedAddr = 0x8000000000;
|
||||
static const uptr kAppAddr = 0x3ff00008000;
|
||||
static const uptr kShadowMask = ~0x3c000000000;
|
||||
};
|
||||
|
||||
struct Mapping48 {
|
||||
static const uptr kShadowAddr = 0x10000;
|
||||
static const uptr kUnionTableAddr = 0x8000000000;
|
||||
static const uptr kUnusedAddr = 0x8000000000;
|
||||
static const uptr kAppAddr = 0xffff00008000;
|
||||
static const uptr kShadowMask = ~0xfffff0000000;
|
||||
};
|
||||
|
@ -64,7 +68,7 @@ enum MappingType {
|
|||
#if defined(__x86_64__)
|
||||
MAPPING_ORIGIN_ADDR,
|
||||
#endif
|
||||
MAPPING_UNION_TABLE_ADDR,
|
||||
MAPPING_UNUSED_ADDR,
|
||||
MAPPING_APP_ADDR,
|
||||
MAPPING_SHADOW_MASK
|
||||
};
|
||||
|
@ -77,7 +81,8 @@ uptr MappingImpl(void) {
|
|||
case MAPPING_ORIGIN_ADDR:
|
||||
return Mapping::kOriginAddr;
|
||||
#endif
|
||||
case MAPPING_UNION_TABLE_ADDR: return Mapping::kUnionTableAddr;
|
||||
case MAPPING_UNUSED_ADDR:
|
||||
return Mapping::kUnusedAddr;
|
||||
case MAPPING_APP_ADDR: return Mapping::kAppAddr;
|
||||
case MAPPING_SHADOW_MASK: return Mapping::kShadowMask;
|
||||
}
|
||||
|
@ -113,9 +118,7 @@ uptr OriginAddr() {
|
|||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
uptr UnionTableAddr() {
|
||||
return MappingArchImpl<MAPPING_UNION_TABLE_ADDR>();
|
||||
}
|
||||
uptr UnusedAddr() { return MappingArchImpl<MAPPING_UNUSED_ADDR>(); }
|
||||
|
||||
ALWAYS_INLINE
|
||||
uptr AppAddr() {
|
||||
|
|
|
@ -17,11 +17,9 @@
|
|||
// and also provides basic-block coverage for every input.
|
||||
//
|
||||
// Build:
|
||||
// 1. Compile this file (DataFlow.cpp) with -fsanitize=dataflow -mllvm
|
||||
// -dfsan-fast-16-labels and -O2.
|
||||
// 1. Compile this file (DataFlow.cpp) with -fsanitize=dataflow and -O2.
|
||||
// 2. Compile DataFlowCallbacks.cpp with -O2 -fPIC.
|
||||
// 3. Build the fuzz target with -g -fsanitize=dataflow
|
||||
// -mllvm -dfsan-fast-16-labels
|
||||
// -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp
|
||||
// 4. Link those together with -fsanitize=dataflow
|
||||
//
|
||||
|
@ -82,7 +80,7 @@ static inline bool BlockIsEntry(size_t BlockIdx) {
|
|||
return __dft.PCsBeg[BlockIdx * 2 + 1] & PCFLAG_FUNC_ENTRY;
|
||||
}
|
||||
|
||||
const int kNumLabels = 16;
|
||||
const int kNumLabels = 8;
|
||||
|
||||
// Prints all instrumented functions.
|
||||
static int PrintFunctions() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -fno-exceptions -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -fno-exceptions -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan %s -fno-exceptions -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions -o %t && %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
//
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
int main(void) {
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_label i_label = 1;
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
dfsan_label new_label = dfsan_get_label(i);
|
||||
|
@ -19,7 +19,7 @@ int main(void) {
|
|||
dfsan_label read_label = dfsan_read_label(&i, sizeof(i));
|
||||
assert(i_label == read_label);
|
||||
|
||||
dfsan_label j_label = dfsan_create_label("j", 0);
|
||||
dfsan_label j_label = 2;
|
||||
dfsan_add_label(j_label, &i, sizeof(i));
|
||||
|
||||
read_label = dfsan_read_label(&i, sizeof(i));
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// RUN: %clang_dfsan %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
|
||||
// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
|
||||
// RUN: %clang_dfsan -DFAST_16_LABELS -mllvm -dfsan-fast-16-labels %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
|
||||
// RUN: %clang_dfsan %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
|
||||
// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DFAST_16_LABELS -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DFAST_16_LABELS -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
|
||||
// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
|
||||
//
|
||||
// Tests custom implementations of various glibc functions.
|
||||
//
|
||||
|
@ -1944,19 +1944,11 @@ void test_snprintf() {
|
|||
void test_fork() {}
|
||||
|
||||
int main(void) {
|
||||
#ifdef FAST_16_LABELS
|
||||
i_label = 1;
|
||||
j_label = 2;
|
||||
k_label = 4;
|
||||
m_label = 8;
|
||||
n_label = 16;
|
||||
#else
|
||||
i_label = dfsan_create_label("i", 0);
|
||||
j_label = dfsan_create_label("j", 0);
|
||||
k_label = dfsan_create_label("k", 0);
|
||||
m_label = dfsan_create_label("m", 0);
|
||||
n_label = dfsan_create_label("n", 0);
|
||||
#endif
|
||||
i_j_label = dfsan_union(i_label, j_label);
|
||||
assert(i_j_label != i_label);
|
||||
assert(i_j_label != j_label);
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
// RUN: %clang_dfsan %s -o %t
|
||||
// RUN: DFSAN_OPTIONS=dump_labels_at_exit=/dev/stdout %run %t 2>&1 | FileCheck %s
|
||||
// RUN: DFSAN_OPTIONS=dump_labels_at_exit=/dev/stdout not %run %t c 2>&1 | FileCheck %s --check-prefix=CHECK-OOL
|
||||
// RUN: DFSAN_OPTIONS=dump_labels_at_exit=/dev/stdout not %run %t u 2>&1 | FileCheck %s --check-prefix=CHECK-OOL
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
// Tests that labels are properly dumped at program termination.
|
||||
|
||||
#include <sanitizer/dfsan_interface.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
int j = 2;
|
||||
dfsan_label j_label = dfsan_create_label("j", 0);
|
||||
dfsan_set_label(j_label, &j, sizeof(j));
|
||||
|
||||
int k = 3;
|
||||
dfsan_label k_label = dfsan_create_label("k", 0);
|
||||
dfsan_set_label(k_label, &k, sizeof(k));
|
||||
|
||||
dfsan_label ij_label = dfsan_get_label(i + j);
|
||||
dfsan_label ijk_label = dfsan_get_label(i + j + k);
|
||||
|
||||
fprintf(stderr, "i %d j %d k %d ij %d ijk %d\n", i_label, j_label, k_label,
|
||||
ij_label, ijk_label);
|
||||
|
||||
// CHECK: 1 0 0 i
|
||||
// CHECK: 2 0 0 j
|
||||
// CHECK: 3 0 0 k
|
||||
// CHECK: 4 1 2
|
||||
// CHECK: 5 3 4
|
||||
|
||||
if (argc > 1) {
|
||||
// Exhaust the labels.
|
||||
unsigned long num_labels = 1 << (sizeof(dfsan_label) * 8);
|
||||
for (unsigned long i = ijk_label + 1; i < num_labels - 2; ++i) {
|
||||
dfsan_label l = dfsan_create_label("l", 0);
|
||||
assert(l == i);
|
||||
}
|
||||
|
||||
// Consume the last available label.
|
||||
dfsan_label l = dfsan_union(5, 6);
|
||||
assert(l == num_labels - 2);
|
||||
|
||||
// Try to allocate another label (either explicitly or by unioning two
|
||||
// existing labels), but expect a crash.
|
||||
if (argv[1][0] == 'c') {
|
||||
l = dfsan_create_label("l", 0);
|
||||
} else {
|
||||
l = dfsan_union(6, 7);
|
||||
}
|
||||
|
||||
// CHECK-OOL: FATAL: DataFlowSanitizer: out of labels
|
||||
// CHECK-OOL: 1 0 0 i
|
||||
// CHECK-OOL: 2 0 0 j
|
||||
// CHECK-OOL: 3 0 0 k
|
||||
// CHECK-OOL: 4 1 2
|
||||
// CHECK-OOL: 5 3 4
|
||||
// CHECK-OOL: 6 0 0
|
||||
// CHECK-OOL: 65534 5 6
|
||||
// CHECK-OOL: 65535 0 0 <init label>
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -81,9 +81,9 @@ int main(int Argc, char *Argv[]) {
|
|||
assert(Argc == 2);
|
||||
|
||||
int I = 1, J = 2;
|
||||
LabelI = dfsan_create_label("I", 0);
|
||||
LabelI = 1;
|
||||
dfsan_set_label(LabelI, &I, sizeof(I));
|
||||
LabelJ = dfsan_create_label("J", 0);
|
||||
LabelJ = 2;
|
||||
dfsan_set_label(LabelJ, &J, sizeof(J));
|
||||
LabelIJ = dfsan_union(LabelI, LabelJ);
|
||||
|
||||
|
@ -113,7 +113,7 @@ int main(int Argc, char *Argv[]) {
|
|||
assert(I != J);
|
||||
|
||||
LenArgv = strlen(Argv[1]);
|
||||
LabelArgv = dfsan_create_label("Argv", 0);
|
||||
LabelArgv = 4;
|
||||
dfsan_set_label(LabelArgv, Argv[1], LenArgv);
|
||||
|
||||
char Buf[64];
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// RUN: %clang_dfsan %s -mllvm -dfsan-fast-16-labels -o %t
|
||||
// RUN: %clang_dfsan %s -o %t
|
||||
// RUN: %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
//
|
||||
// Tests fast16labels mode.
|
||||
|
||||
#include <sanitizer/dfsan_interface.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -19,11 +17,11 @@ int main(int argc, char *argv[]) {
|
|||
int a = 10;
|
||||
int b = 20;
|
||||
dfsan_set_label(8, &a, sizeof(a));
|
||||
dfsan_set_label(512, &b, sizeof(b));
|
||||
dfsan_set_label(128, &b, sizeof(b));
|
||||
int c = foo(a, b);
|
||||
printf("A: 0x%x\n", dfsan_get_label(a));
|
||||
printf("B: 0x%x\n", dfsan_get_label(b));
|
||||
dfsan_label l = dfsan_get_label(c);
|
||||
printf("C: 0x%x\n", l);
|
||||
assert(l == 520); // OR of the other two labels.
|
||||
assert(l == 136); // OR of the other two labels.
|
||||
}
|
|
@ -14,7 +14,7 @@ int f(int i) {
|
|||
|
||||
int main(void) {
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_label i_label = 2;
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
// CHECK: WARNING: DataFlowSanitizer: call to uninstrumented function f
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Tests dfsan_flush().
|
||||
// RUN: %clang_dfsan %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -o %t && %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -10,19 +10,22 @@
|
|||
|
||||
int f(int x) {
|
||||
int j = 2;
|
||||
dfsan_label j_label = dfsan_create_label("j", 0);
|
||||
dfsan_label j_label = 2;
|
||||
dfsan_set_label(j_label, &j, sizeof(j));
|
||||
return x + j;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_label i_label = 4;
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
dfsan_label ij_label = dfsan_get_label(f(i));
|
||||
assert(dfsan_has_label(ij_label, i_label));
|
||||
assert(dfsan_has_label_with_desc(ij_label, "j"));
|
||||
|
||||
/* Must be consistent with the one in f(). */
|
||||
dfsan_label j_label = 2;
|
||||
assert(dfsan_has_label(ij_label, 2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
// Run a number of threads that create new chained origins, then fork
|
||||
// and verify that origin reads do not deadlock in the child process.
|
||||
//
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t
|
||||
// RUN: %clangxx_dfsan %s -o %t
|
||||
// RUN: %run %t 2>&1 | FileCheck %s
|
||||
//
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 %s -o %t
|
||||
// RUN: DFSAN_OPTIONS=store_context_size=1000,origin_history_size=0,origin_history_per_stack_limit=0 %run %t 2>&1 | FileCheck %s
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clang_dfsan -mllvm -dfsan-fast-16-labels -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && %run %t
|
||||
//
|
||||
// Tests custom implementations of various glibc functions.
|
||||
//
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
// RUN: %clang_dfsan -DLIB -c %s -o %t.lib.o && \
|
||||
// RUN: %clang_dfsan -c %s -o %t.o && \
|
||||
// RUN: %clang_dfsan %t.lib.o %t.o -o %t.bin && \
|
||||
// RUN: %run %t.bin
|
||||
|
||||
// RUN: %clang_dfsan -mllvm -dfsan-args-abi -DLIB -c %s -o %t.lib.o && \
|
||||
// RUN: %clang_dfsan -mllvm -dfsan-args-abi -c %s -o %t.o && \
|
||||
// RUN: %clang_dfsan -mllvm -dfsan-args-abi %t.o %t.lib.o -o %t.bin && \
|
||||
// RUN: %run %t.bin
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
#include <sanitizer/dfsan_interface.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef LIB
|
||||
// Compiling this file with and without LIB defined allows this file to be
|
||||
// built as two separate translation units. This ensures that the code
|
||||
// can not be optimized in a way that removes behavior we wish to test. For
|
||||
// example, computing a value should cause labels to be allocated only if
|
||||
// the computation is actually done. Putting the computation here prevents
|
||||
// the compiler from optimizing away the computation (and labeling) that
|
||||
// tests wish to verify.
|
||||
|
||||
int add_in_separate_translation_unit(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int multiply_in_separate_translation_unit(int a, int b) {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int add_in_separate_translation_unit(int i, int j);
|
||||
int multiply_in_separate_translation_unit(int i, int j);
|
||||
|
||||
int main(void) {
|
||||
size_t label_count;
|
||||
|
||||
// No labels allocated yet.
|
||||
label_count = dfsan_get_label_count();
|
||||
assert(0 == label_count);
|
||||
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
// One label allocated for i.
|
||||
label_count = dfsan_get_label_count();
|
||||
assert(1u == label_count);
|
||||
|
||||
int j = 2;
|
||||
dfsan_label j_label = dfsan_create_label("j", 0);
|
||||
dfsan_set_label(j_label, &j, sizeof(j));
|
||||
|
||||
// Check that a new label was allocated for j.
|
||||
label_count = dfsan_get_label_count();
|
||||
assert(2u == label_count);
|
||||
|
||||
// Create a value that combines i and j.
|
||||
int i_plus_j = add_in_separate_translation_unit(i, j);
|
||||
|
||||
// Check that a label was created for the union of i and j.
|
||||
label_count = dfsan_get_label_count();
|
||||
assert(3u == label_count);
|
||||
|
||||
// Combine i and j in a different way. Check that the existing label is
|
||||
// reused, and a new label is not created.
|
||||
int j_times_i = multiply_in_separate_translation_unit(j, i);
|
||||
label_count = dfsan_get_label_count();
|
||||
assert(3u == label_count);
|
||||
assert(dfsan_get_label(i_plus_j) == dfsan_get_label(j_times_i));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // #ifdef LIB
|
|
@ -1,10 +1,10 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: %clang_dfsan -gmlt %s -o %t && %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
uint64_t a = 10;
|
||||
dfsan_set_label(8, &a, sizeof(a));
|
||||
dfsan_set_label(1, &a, sizeof(a));
|
||||
size_t origin_addr =
|
||||
(((size_t)&a & ~0x700000000000LL + 0x200000000000LL) & ~0x3UL);
|
||||
(((size_t)&a & ~0x600000000000LL + 0x100000000000LL) & ~0x3UL);
|
||||
asm("mov %0, %%rax": :"r"(origin_addr));
|
||||
asm("movq $0, (%rax)");
|
||||
dfsan_print_origin_trace(&a, "invalid");
|
||||
}
|
||||
|
||||
// CHECK: Taint value 0x8 (at {{.*}}) origin tracking (invalid)
|
||||
// CHECK: Taint value 0x8 (at {{.*}}) has invalid origin tracking. This can be a DFSan bug.
|
||||
// CHECK: Taint value 0x1 (at {{.*}}) origin tracking (invalid)
|
||||
// CHECK: Taint value 0x1 (at {{.*}}) has invalid origin tracking. This can be a DFSan bug.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
//
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
// RUN: %clang_dfsan -gmlt -DTEST64 -DALIGN=8 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DTEST64 -DALIGN=8 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DTEST32 -DALIGN=4 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DTEST32 -DALIGN=4 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DALIGN=2 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DALIGN=2 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// rUN: %clang_dfsan -DTEST64 -DALIGN=5 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// rUN: %run %t >%t.out 2>&1
|
||||
// rUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
//
|
||||
// rUN: %clang_dfsan -DTEST32 -DALIGN=3 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// rUN: %run %t >%t.out 2>&1
|
||||
// rUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DALIGN=1 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DTEST64 -DALIGN=4 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DTEST32 -DALIGN=2 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DALIGN=1 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
//
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t
|
||||
//
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: DFSAN_OPTIONS=origin_history_size=2 %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK2 < %t.out
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out
|
||||
//
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out
|
||||
//
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=2 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=2 %s -o %t && \
|
||||
// RUN: %run %t > %t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK0 < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DOFFSET=10 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK10 < %t.out
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK < %t.out
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
// Origin tracking uses ChainedOriginDepot that is not async signal safe, so we
|
||||
// do not track origins inside signal handlers.
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DUSE_SIGNAL_ACTION -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DUSE_SIGNAL_ACTION -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -DUSE_SIGNAL_ACTION -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -DUSE_SIGNAL_ACTION -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
// Origin tracking uses ChainedOriginDepot that is not async signal safe, so we
|
||||
// do not track origins inside signal handlers.
|
||||
//
|
||||
// RUN: %clangxx_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clangxx_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clangxx_dfsan -gmlt -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clangxx_dfsan -gmlt -mllvm -dfsan-instrument-with-call-threshold=0 -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O0 -DO0 -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan %s -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O0 -DO0 -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan %s -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -13,15 +13,15 @@ int main(void) {
|
|||
assert(dfsan_union(0, 0) == 0);
|
||||
|
||||
int i = 1;
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_label i_label = 1;
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
|
||||
int j = 2;
|
||||
dfsan_label j_label = dfsan_create_label("j", 0);
|
||||
dfsan_label j_label = 2;
|
||||
dfsan_set_label(j_label, &j, sizeof(j));
|
||||
|
||||
int k = 3;
|
||||
dfsan_label k_label = dfsan_create_label("k", 0);
|
||||
dfsan_label k_label = 4;
|
||||
dfsan_set_label(k_label, &k, sizeof(k));
|
||||
|
||||
int k2 = 4;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// RUN: %clang_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan %s -o %t && %run %t
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \
|
||||
// RUN: %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s < %t.out
|
||||
//
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// DFSAN_OPTIONS=no_huge_pages_for_shadow=false RUN: %clang_dfsan %s -o %t && setarch `uname -m` -R %run %t
|
||||
// DFSAN_OPTIONS=no_huge_pages_for_shadow=true RUN: %clang_dfsan %s -o %t && setarch `uname -m` -R %run %t
|
||||
// DFSAN_OPTIONS=no_huge_pages_for_shadow=false RUN: %clang_dfsan %s -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -o %t && setarch `uname -m` -R %run %t
|
||||
// DFSAN_OPTIONS=no_huge_pages_for_shadow=true RUN: %clang_dfsan %s -DORIGIN_TRACKING -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-origins=1 -o %t && setarch `uname -m` -R %run %t
|
||||
// DFSAN_OPTIONS=no_huge_pages_for_shadow=false RUN: %clang_dfsan %s -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -o %t && setarch `uname -m` -R %run %t
|
||||
// DFSAN_OPTIONS=no_huge_pages_for_shadow=true RUN: %clang_dfsan %s -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -o %t && setarch `uname -m` -R %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
@ -45,7 +45,7 @@ int main(int argc, char **argv) {
|
|||
size_t after_mmap = get_rss_kb();
|
||||
|
||||
// store labels to all addresses. The overhead is 2x.
|
||||
const dfsan_label label = dfsan_create_label("l", 0);
|
||||
const dfsan_label label = 8;
|
||||
char val = 0xff;
|
||||
dfsan_set_label(label, &val, sizeof(val));
|
||||
memset(p, val, map_size);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// RUN: %clang_dfsan -DUSE_SIGNAL_ACTION -mllvm -dfsan-fast-16-labels=true %s -o %t && \
|
||||
// RUN: %run %t
|
||||
// RUN: %clang_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan -DUSE_SIGNAL_ACTION %s -o %t && %run %t
|
||||
// RUN: %clang_dfsan %s -o %t && %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clangxx_dfsan -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true %s -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-fast-16-labels=true -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan %s -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 %s -o %t && %run %t
|
||||
// RUN: %clangxx_dfsan -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && %run %t
|
||||
//
|
||||
// Test that the state of shadows from a sigaction handler are consistent.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// RUN: %clang_dfsan %s -O1 -mllvm -dfsan-fast-16-labels=true -DFAST16_O1 -o %t && %run %t
|
||||
// RUN: %clang_dfsan %s -O1 -DO1 -o %t && %run %t
|
||||
// RUN: %clang_dfsan %s -O0 -mllvm -dfsan-fast-16-labels=true -DFAST16_O0 -o %t && %run %t
|
||||
// RUN: %clang_dfsan %s -O1 -o %t && %run %t
|
||||
// RUN: %clang_dfsan %s -O0 -DO0 -o %t && %run %t
|
||||
//
|
||||
// REQUIRES: x86_64-target-arch
|
||||
|
@ -40,13 +38,8 @@ Pair copy_pair2(const Pair pair0) {
|
|||
int main(void) {
|
||||
int i = 1;
|
||||
char *ptr = NULL;
|
||||
#if defined(FAST16_O1) || defined(FAST16_O0)
|
||||
dfsan_label i_label = 1;
|
||||
dfsan_label ptr_label = 2;
|
||||
#else
|
||||
dfsan_label i_label = dfsan_create_label("i", 0);
|
||||
dfsan_label ptr_label = dfsan_create_label("ptr", 0);
|
||||
#endif
|
||||
dfsan_set_label(i_label, &i, sizeof(i));
|
||||
dfsan_set_label(ptr_label, &ptr, sizeof(ptr));
|
||||
|
||||
|
@ -56,12 +49,7 @@ int main(void) {
|
|||
|
||||
dfsan_label i1_label = dfsan_read_label(&i1, sizeof(i1));
|
||||
dfsan_label ptr1_label = dfsan_read_label(&ptr1, sizeof(ptr1));
|
||||
#if defined(O0) || defined(O1)
|
||||
assert(dfsan_has_label(i1_label, i_label));
|
||||
assert(dfsan_has_label(i1_label, ptr_label));
|
||||
assert(dfsan_has_label(ptr1_label, i_label));
|
||||
assert(dfsan_has_label(ptr1_label, ptr_label));
|
||||
#elif defined(FAST16_O0)
|
||||
#if defined(O0)
|
||||
assert(i1_label == (i_label | ptr_label));
|
||||
assert(ptr1_label == (i_label | ptr_label));
|
||||
#else
|
||||
|
@ -75,12 +63,7 @@ int main(void) {
|
|||
|
||||
dfsan_label i2_label = dfsan_read_label(&i2, sizeof(i2));
|
||||
dfsan_label ptr2_label = dfsan_read_label(&ptr2, sizeof(ptr2));
|
||||
#if defined(O0) || defined(O1)
|
||||
assert(dfsan_has_label(i2_label, i_label));
|
||||
assert(dfsan_has_label(i2_label, ptr_label));
|
||||
assert(dfsan_has_label(ptr2_label, i_label));
|
||||
assert(dfsan_has_label(ptr2_label, ptr_label));
|
||||
#elif defined(FAST16_O0)
|
||||
#if defined(O0)
|
||||
assert(i2_label == (i_label | ptr_label));
|
||||
assert(ptr2_label == (i_label | ptr_label));
|
||||
#else
|
||||
|
@ -94,12 +77,7 @@ int main(void) {
|
|||
|
||||
dfsan_label i3_label = dfsan_read_label(&i3, sizeof(i3));
|
||||
dfsan_label ptr3_label = dfsan_read_label(&ptr3, sizeof(ptr3));
|
||||
#if defined(O0) || defined(O1)
|
||||
assert(dfsan_has_label(i3_label, i_label));
|
||||
assert(dfsan_has_label(i3_label, ptr_label));
|
||||
assert(dfsan_has_label(ptr3_label, i_label));
|
||||
assert(dfsan_has_label(ptr3_label, ptr_label));
|
||||
#elif defined(FAST16_O0)
|
||||
#if defined(O0)
|
||||
assert(i3_label == (i_label | ptr_label));
|
||||
assert(ptr3_label == (i_label | ptr_label));
|
||||
#else
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
REQUIRES: linux, x86_64
|
||||
|
||||
# Build the tracer and the test.
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fPIC %S/../../lib/fuzzer/dataflow/DataFlowCallbacks.cpp -o %t-DataFlowCallbacks.o
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/ThreeFunctionsTest.cpp %t-DataFlow*.o -o %t-ThreeFunctionsTestDF
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/Labels20Test.cpp %t-DataFlow*.o -o %t-Labels20TestDF
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/ThreeFunctionsTest.cpp %t-DataFlow*.o -o %t-ThreeFunctionsTestDF
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/Labels20Test.cpp %t-DataFlow*.o -o %t-Labels20TestDF
|
||||
RUN: %cpp_compiler %S/ThreeFunctionsTest.cpp -o %t-ThreeFunctionsTest
|
||||
|
||||
# Dump the function list.
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
REQUIRES: linux, x86_64
|
||||
|
||||
# Build the tracer and the test.
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fPIC %S/../../lib/fuzzer/dataflow/DataFlowCallbacks.cpp -o %t-DataFlowCallbacks.o
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/OnlySomeBytesTest.cpp %t-DataFlow*.o -o %t-DFT
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/OnlySomeBytesTest.cpp %t-DataFlow*.o -o %t-DFT
|
||||
RUN: %cpp_compiler %S/OnlySomeBytesTest.cpp -o %t-Fuzz
|
||||
|
||||
# Test that the fork mode can collect and use the DFT
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
REQUIRES: linux, x86_64
|
||||
|
||||
# Build the tracer and the test.
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fsanitize=dataflow %S/../../lib/fuzzer/dataflow/DataFlow.cpp -o %t-DataFlow.o
|
||||
RUN: %no_fuzzer_cpp_compiler -c -fno-sanitize=all -fPIC %S/../../lib/fuzzer/dataflow/DataFlowCallbacks.cpp -o %t-DataFlowCallbacks.o
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -mllvm -dfsan-fast-16-labels -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/OnlySomeBytesTest.cpp %t-DataFlow*.o -o %t-DFT
|
||||
RUN: %no_fuzzer_cpp_compiler -fno-sanitize=all -fsanitize=dataflow -fsanitize-coverage=trace-pc-guard,pc-table,bb,trace-cmp %S/OnlySomeBytesTest.cpp %t-DataFlow*.o -o %t-DFT
|
||||
RUN: %cpp_compiler %S/OnlySomeBytesTest.cpp -o %t-Fuzz
|
||||
|
||||
# Prepare the inputs.
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
/// The analysis is based on automatic propagation of data flow labels (also
|
||||
/// known as taint labels) through a program as it performs computation.
|
||||
///
|
||||
/// There are two possible memory layouts. In the first one, each byte of
|
||||
/// application memory is backed by a shadow memory byte. The shadow byte can
|
||||
/// represent up to 8 labels. To enable this you must specify the
|
||||
/// -dfsan-fast-8-labels flag. On Linux/x86_64, memory is then laid out as
|
||||
/// follows:
|
||||
/// Each byte of application memory is backed by a shadow memory byte. The
|
||||
/// shadow byte can represent up to 8 labels. On Linux/x86_64, memory is then
|
||||
/// laid out as follows:
|
||||
///
|
||||
/// +--------------------+ 0x800000000000 (top of memory)
|
||||
/// | application memory |
|
||||
|
@ -30,11 +28,11 @@
|
|||
/// | |
|
||||
/// | unused |
|
||||
/// | |
|
||||
/// +--------------------+ 0x300200000000 (kUnusedAddr)
|
||||
/// | union table |
|
||||
/// +--------------------+ 0x300000000000 (kUnionTableAddr)
|
||||
/// +--------------------+ 0x300000000000 (kUnusedAddr)
|
||||
/// | origin |
|
||||
/// +--------------------+ 0x200000008000 (kOriginAddr)
|
||||
/// | unused |
|
||||
/// +--------------------+ 0x200000000000
|
||||
/// | shadow memory |
|
||||
/// +--------------------+ 0x100000008000 (kShadowAddr)
|
||||
/// | unused |
|
||||
|
@ -43,34 +41,9 @@
|
|||
/// +--------------------+ 0x000000000000
|
||||
///
|
||||
///
|
||||
/// In the second memory layout, each byte of application memory is backed by
|
||||
/// two bytes of shadow memory which hold the label. That means we can represent
|
||||
/// either 16 labels (with -dfsan-fast-16-labels flag) or 2^16 labels (on the
|
||||
/// default legacy mode) per byte. On Linux/x86_64, memory is then laid out as
|
||||
/// follows:
|
||||
///
|
||||
/// +--------------------+ 0x800000000000 (top of memory)
|
||||
/// | application memory |
|
||||
/// +--------------------+ 0x700000008000 (kAppAddr)
|
||||
/// | |
|
||||
/// | unused |
|
||||
/// | |
|
||||
/// +--------------------+ 0x300200000000 (kUnusedAddr)
|
||||
/// | union table |
|
||||
/// +--------------------+ 0x300000000000 (kUnionTableAddr)
|
||||
/// | origin |
|
||||
/// +--------------------+ 0x200000008000 (kOriginAddr)
|
||||
/// | shadow memory |
|
||||
/// +--------------------+ 0x000000010000 (kShadowAddr)
|
||||
/// | reserved by kernel |
|
||||
/// +--------------------+ 0x000000000000
|
||||
///
|
||||
///
|
||||
/// To derive a shadow memory address from an application memory address,
|
||||
/// bits 44-46 are cleared to bring the address into the range
|
||||
/// [0x000000008000,0x100000000000). Then the address is shifted left by 1 to
|
||||
/// account for the double byte representation of shadow labels and move the
|
||||
/// address into the shadow memory range. See the function
|
||||
/// To derive a shadow memory address from an application memory address, bits
|
||||
/// 45-46 are cleared to bring the address into the range
|
||||
/// [0x100000008000,0x200000000000). See the function
|
||||
/// DataFlowSanitizer::getShadowAddress below.
|
||||
///
|
||||
/// For more information, please refer to the design document:
|
||||
|
@ -230,22 +203,6 @@ static cl::opt<bool> ClEventCallbacks(
|
|||
cl::desc("Insert calls to __dfsan_*_callback functions on data events."),
|
||||
cl::Hidden, cl::init(false));
|
||||
|
||||
// Use a distinct bit for each base label, enabling faster unions with less
|
||||
// instrumentation. Limits the max number of base labels to 16.
|
||||
static cl::opt<bool> ClFast16Labels(
|
||||
"dfsan-fast-16-labels",
|
||||
cl::desc("Use more efficient instrumentation, limiting the number of "
|
||||
"labels to 16."),
|
||||
cl::Hidden, cl::init(false));
|
||||
|
||||
// Use a distinct bit for each base label, enabling faster unions with less
|
||||
// instrumentation. Limits the max number of base labels to 8.
|
||||
static cl::opt<bool> ClFast8Labels(
|
||||
"dfsan-fast-8-labels",
|
||||
cl::desc("Use more efficient instrumentation, limiting the number of "
|
||||
"labels to 8."),
|
||||
cl::Hidden, cl::init(false));
|
||||
|
||||
// Controls whether the pass tracks the control flow of select instructions.
|
||||
static cl::opt<bool> ClTrackSelectControlFlow(
|
||||
"dfsan-track-select-control-flow",
|
||||
|
@ -387,6 +344,8 @@ class DataFlowSanitizer {
|
|||
friend struct DFSanFunction;
|
||||
friend class DFSanVisitor;
|
||||
|
||||
enum { ShadowWidthBits = 8, ShadowWidthBytes = ShadowWidthBits / 8 };
|
||||
|
||||
enum {
|
||||
OriginWidthBits = 32,
|
||||
OriginWidthBytes = OriginWidthBits / 8
|
||||
|
@ -428,15 +387,11 @@ class DataFlowSanitizer {
|
|||
WK_Custom
|
||||
};
|
||||
|
||||
unsigned ShadowWidthBits;
|
||||
unsigned ShadowWidthBytes;
|
||||
|
||||
Module *Mod;
|
||||
LLVMContext *Ctx;
|
||||
Type *Int8Ptr;
|
||||
IntegerType *OriginTy;
|
||||
PointerType *OriginPtrTy;
|
||||
ConstantInt *OriginBase;
|
||||
ConstantInt *ZeroOrigin;
|
||||
/// The shadow type for all primitive types and vector types.
|
||||
IntegerType *PrimitiveShadowTy;
|
||||
|
@ -444,14 +399,14 @@ class DataFlowSanitizer {
|
|||
IntegerType *IntptrTy;
|
||||
ConstantInt *ZeroPrimitiveShadow;
|
||||
ConstantInt *ShadowPtrMask;
|
||||
ConstantInt *ShadowPtrMul;
|
||||
ConstantInt *ShadowBase;
|
||||
ConstantInt *OriginBase;
|
||||
Constant *ArgTLS;
|
||||
ArrayType *ArgOriginTLSTy;
|
||||
Constant *ArgOriginTLS;
|
||||
Constant *RetvalTLS;
|
||||
Constant *RetvalOriginTLS;
|
||||
Constant *ExternalShadowMask;
|
||||
FunctionType *DFSanUnionFnTy;
|
||||
FunctionType *DFSanUnionLoadFnTy;
|
||||
FunctionType *DFSanLoadLabelAndOriginFnTy;
|
||||
FunctionType *DFSanUnimplementedFnTy;
|
||||
|
@ -465,10 +420,7 @@ class DataFlowSanitizer {
|
|||
FunctionType *DFSanChainOriginIfTaintedFnTy;
|
||||
FunctionType *DFSanMemOriginTransferFnTy;
|
||||
FunctionType *DFSanMaybeStoreOriginFnTy;
|
||||
FunctionCallee DFSanUnionFn;
|
||||
FunctionCallee DFSanCheckedUnionFn;
|
||||
FunctionCallee DFSanUnionLoadFn;
|
||||
FunctionCallee DFSanUnionLoadFastLabelsFn;
|
||||
FunctionCallee DFSanLoadLabelAndOriginFn;
|
||||
FunctionCallee DFSanUnimplementedFn;
|
||||
FunctionCallee DFSanSetLabelFn;
|
||||
|
@ -510,7 +462,6 @@ class DataFlowSanitizer {
|
|||
void initializeCallbackFunctions(Module &M);
|
||||
void initializeRuntimeFunctions(Module &M);
|
||||
void injectMetadataGlobals(Module &M);
|
||||
|
||||
bool init(Module &M);
|
||||
|
||||
/// Advances \p OriginAddr to point to the next 32-bit origin and then loads
|
||||
|
@ -518,19 +469,15 @@ class DataFlowSanitizer {
|
|||
Value *loadNextOrigin(Instruction *Pos, Align OriginAlign,
|
||||
Value **OriginAddr);
|
||||
|
||||
/// Returns whether fast8 or fast16 mode has been specified.
|
||||
bool hasFastLabelsEnabled();
|
||||
|
||||
/// Returns whether the given load byte size is amenable to inlined
|
||||
/// optimization patterns.
|
||||
bool hasLoadSizeForFastPath(uint64_t Size);
|
||||
|
||||
/// Returns whether the pass tracks origins. Support only fast16 mode in TLS
|
||||
/// ABI mode.
|
||||
/// Returns whether the pass tracks origins. Supports only TLS ABI mode.
|
||||
bool shouldTrackOrigins();
|
||||
|
||||
/// Returns whether the pass tracks labels for struct fields and array
|
||||
/// indices. Support only fast16 mode in TLS ABI mode.
|
||||
/// indices. Supports only TLS ABI mode.
|
||||
bool shouldTrackFieldsAndIndices();
|
||||
|
||||
/// Returns a zero constant with the shadow type of OrigTy.
|
||||
|
@ -590,7 +537,6 @@ struct DFSanFunction {
|
|||
|
||||
DenseSet<Instruction *> SkipInsts;
|
||||
std::vector<Value *> NonZeroChecks;
|
||||
bool AvoidNewBlocks;
|
||||
|
||||
struct CachedShadow {
|
||||
BasicBlock *Block; // The block where Shadow is defined.
|
||||
|
@ -608,9 +554,6 @@ struct DFSanFunction {
|
|||
DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI)
|
||||
: DFS(DFS), F(F), IA(DFS.getInstrumentedABI()), IsNativeABI(IsNativeABI) {
|
||||
DT.recalculate(*F);
|
||||
// FIXME: Need to track down the register allocator issue which causes poor
|
||||
// performance in pathological cases with large numbers of basic blocks.
|
||||
AvoidNewBlocks = F->size() > 1000;
|
||||
}
|
||||
|
||||
/// Computes the shadow address for a given function argument.
|
||||
|
@ -702,13 +645,9 @@ private:
|
|||
/// Returns the shadow value of an argument A.
|
||||
Value *getShadowForTLSArgument(Argument *A);
|
||||
|
||||
/// The fast path of loading shadow in legacy mode.
|
||||
Value *loadLegacyShadowFast(Value *ShadowAddr, uint64_t Size,
|
||||
Align ShadowAlign, Instruction *Pos);
|
||||
|
||||
/// The fast path of loading shadow in fast-16-label mode.
|
||||
/// The fast path of loading shadows.
|
||||
std::pair<Value *, Value *>
|
||||
loadFast16ShadowFast(Value *ShadowAddr, Value *OriginAddr, uint64_t Size,
|
||||
loadShadowFast(Value *ShadowAddr, Value *OriginAddr, uint64_t Size,
|
||||
Align ShadowAlign, Align OriginAlign, Value *FirstOrigin,
|
||||
Instruction *Pos);
|
||||
|
||||
|
@ -820,14 +759,6 @@ private:
|
|||
|
||||
DataFlowSanitizer::DataFlowSanitizer(
|
||||
const std::vector<std::string> &ABIListFiles) {
|
||||
if (ClFast8Labels && ClFast16Labels) {
|
||||
report_fatal_error(
|
||||
"cannot set both -dfsan-fast-8-labels and -dfsan-fast-16-labels");
|
||||
}
|
||||
|
||||
ShadowWidthBits = ClFast8Labels ? 8 : 16;
|
||||
ShadowWidthBytes = ShadowWidthBits / 8;
|
||||
|
||||
std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
|
||||
llvm::append_range(AllABIListFiles, ClABIListFiles);
|
||||
// FIXME: should we propagate vfs::FileSystem to this constructor?
|
||||
|
@ -922,11 +853,6 @@ bool DataFlowSanitizer::isZeroShadow(Value *V) {
|
|||
return isa<ConstantAggregateZero>(V);
|
||||
}
|
||||
|
||||
bool DataFlowSanitizer::hasFastLabelsEnabled() {
|
||||
static const bool HasFastLabelsEnabled = ClFast8Labels || ClFast16Labels;
|
||||
return HasFastLabelsEnabled;
|
||||
}
|
||||
|
||||
bool DataFlowSanitizer::hasLoadSizeForFastPath(uint64_t Size) {
|
||||
uint64_t ShadowSize = Size * ShadowWidthBytes;
|
||||
return ShadowSize % 8 == 0 || ShadowSize == 4;
|
||||
|
@ -934,14 +860,12 @@ bool DataFlowSanitizer::hasLoadSizeForFastPath(uint64_t Size) {
|
|||
|
||||
bool DataFlowSanitizer::shouldTrackOrigins() {
|
||||
static const bool ShouldTrackOrigins =
|
||||
ClTrackOrigins && getInstrumentedABI() == DataFlowSanitizer::IA_TLS &&
|
||||
hasFastLabelsEnabled();
|
||||
ClTrackOrigins && getInstrumentedABI() == DataFlowSanitizer::IA_TLS;
|
||||
return ShouldTrackOrigins;
|
||||
}
|
||||
|
||||
bool DataFlowSanitizer::shouldTrackFieldsAndIndices() {
|
||||
return getInstrumentedABI() == DataFlowSanitizer::IA_TLS &&
|
||||
hasFastLabelsEnabled();
|
||||
return getInstrumentedABI() == DataFlowSanitizer::IA_TLS;
|
||||
}
|
||||
|
||||
Constant *DataFlowSanitizer::getZeroShadow(Type *OrigTy) {
|
||||
|
@ -1100,21 +1024,19 @@ bool DataFlowSanitizer::init(Module &M) {
|
|||
PrimitiveShadowPtrTy = PointerType::getUnqual(PrimitiveShadowTy);
|
||||
IntptrTy = DL.getIntPtrType(*Ctx);
|
||||
ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
|
||||
ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes);
|
||||
OriginBase = ConstantInt::get(IntptrTy, 0x200000000000LL);
|
||||
ZeroOrigin = ConstantInt::getSigned(OriginTy, 0);
|
||||
|
||||
// TODO: these should be platform-specific and set in the switch-stmt below.
|
||||
ShadowBase = ConstantInt::get(IntptrTy, 0x100000008000LL);
|
||||
OriginBase = ConstantInt::get(IntptrTy, 0x200000008000LL);
|
||||
|
||||
switch (TargetTriple.getArch()) {
|
||||
case Triple::x86_64:
|
||||
ShadowPtrMask = ClFast8Labels
|
||||
? ConstantInt::getSigned(IntptrTy, ~0x600000000000LL)
|
||||
: ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x600000000000LL);
|
||||
break;
|
||||
case Triple::mips64:
|
||||
case Triple::mips64el:
|
||||
ShadowPtrMask = ClFast8Labels
|
||||
? ConstantInt::getSigned(IntptrTy, ~0xE000000000LL)
|
||||
: ConstantInt::getSigned(IntptrTy, ~0xF000000000LL);
|
||||
ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xE000000000LL);
|
||||
break;
|
||||
case Triple::aarch64:
|
||||
case Triple::aarch64_be:
|
||||
|
@ -1125,9 +1047,6 @@ bool DataFlowSanitizer::init(Module &M) {
|
|||
report_fatal_error("unsupported triple");
|
||||
}
|
||||
|
||||
Type *DFSanUnionArgs[2] = {PrimitiveShadowTy, PrimitiveShadowTy};
|
||||
DFSanUnionFnTy =
|
||||
FunctionType::get(PrimitiveShadowTy, DFSanUnionArgs, /*isVarArg=*/false);
|
||||
Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
|
||||
DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
|
||||
/*isVarArg=*/false);
|
||||
|
@ -1306,32 +1225,6 @@ Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT,
|
|||
|
||||
// Initialize DataFlowSanitizer runtime functions and declare them in the module
|
||||
void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::ReadNone);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
|
||||
Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
|
||||
DFSanUnionFn =
|
||||
Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy, AL);
|
||||
}
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::ReadNone);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
|
||||
Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
|
||||
AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
|
||||
DFSanCheckedUnionFn =
|
||||
Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy, AL);
|
||||
}
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
|
@ -1343,17 +1236,6 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
|
|||
DFSanUnionLoadFn =
|
||||
Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL);
|
||||
}
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::NoUnwind);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
Attribute::ReadOnly);
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex,
|
||||
Attribute::ZExt);
|
||||
DFSanUnionLoadFastLabelsFn = Mod->getOrInsertFunction(
|
||||
"__dfsan_union_load_fast16labels", DFSanUnionLoadFnTy, AL);
|
||||
}
|
||||
{
|
||||
AttributeList AL;
|
||||
AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||
|
@ -1406,13 +1288,8 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
|
|||
"__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
|
||||
}
|
||||
|
||||
DFSanRuntimeFunctions.insert(DFSanUnionFn.getCallee()->stripPointerCasts());
|
||||
DFSanRuntimeFunctions.insert(
|
||||
DFSanCheckedUnionFn.getCallee()->stripPointerCasts());
|
||||
DFSanRuntimeFunctions.insert(
|
||||
DFSanUnionLoadFn.getCallee()->stripPointerCasts());
|
||||
DFSanRuntimeFunctions.insert(
|
||||
DFSanUnionLoadFastLabelsFn.getCallee()->stripPointerCasts());
|
||||
DFSanRuntimeFunctions.insert(
|
||||
DFSanLoadLabelAndOriginFn.getCallee()->stripPointerCasts());
|
||||
DFSanRuntimeFunctions.insert(
|
||||
|
@ -1878,13 +1755,16 @@ Value *DataFlowSanitizer::getShadowOffset(Value *Addr, IRBuilder<> &IRB) {
|
|||
std::pair<Value *, Value *>
|
||||
DataFlowSanitizer::getShadowOriginAddress(Value *Addr, Align InstAlignment,
|
||||
Instruction *Pos) {
|
||||
// Returns ((Addr & shadow_mask) + origin_base) & ~4UL
|
||||
// Returns ((Addr & shadow_mask) + origin_base - shadow_base) & ~4UL
|
||||
IRBuilder<> IRB(Pos);
|
||||
Value *ShadowOffset = getShadowOffset(Addr, IRB);
|
||||
Value *ShadowPtr = getShadowAddress(Addr, Pos, ShadowOffset);
|
||||
Value *OriginPtr = nullptr;
|
||||
if (shouldTrackOrigins()) {
|
||||
Value *OriginLong = IRB.CreateAdd(ShadowOffset, OriginBase);
|
||||
static Value *OriginByShadowOffset = ConstantInt::get(
|
||||
IntptrTy, OriginBase->getZExtValue() - ShadowBase->getZExtValue());
|
||||
|
||||
Value *OriginLong = IRB.CreateAdd(ShadowOffset, OriginByShadowOffset);
|
||||
const Align Alignment = llvm::assumeAligned(InstAlignment.value());
|
||||
// When alignment is >= 4, Addr must be aligned to 4, otherwise it is UB.
|
||||
// So Mask is unnecessary.
|
||||
|
@ -1900,15 +1780,11 @@ DataFlowSanitizer::getShadowOriginAddress(Value *Addr, Align InstAlignment,
|
|||
Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos,
|
||||
Value *ShadowOffset) {
|
||||
IRBuilder<> IRB(Pos);
|
||||
|
||||
if (!ShadowPtrMul->isOne())
|
||||
ShadowOffset = IRB.CreateMul(ShadowOffset, ShadowPtrMul);
|
||||
|
||||
return IRB.CreateIntToPtr(ShadowOffset, PrimitiveShadowPtrTy);
|
||||
}
|
||||
|
||||
Value *DataFlowSanitizer::getShadowAddress(Value *Addr, Instruction *Pos) {
|
||||
// Returns (Addr & shadow_mask) x 2
|
||||
// Returns (Addr & shadow_mask)
|
||||
IRBuilder<> IRB(Pos);
|
||||
Value *ShadowOffset = getShadowOffset(Addr, IRB);
|
||||
return getShadowAddress(Addr, Pos, ShadowOffset);
|
||||
|
@ -1961,37 +1837,8 @@ Value *DFSanFunction::combineShadows(Value *V1, Value *V2, Instruction *Pos) {
|
|||
Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
|
||||
|
||||
IRBuilder<> IRB(Pos);
|
||||
if (DFS.hasFastLabelsEnabled()) {
|
||||
CCS.Block = Pos->getParent();
|
||||
CCS.Shadow = IRB.CreateOr(PV1, PV2);
|
||||
} else if (AvoidNewBlocks) {
|
||||
CallInst *Call = IRB.CreateCall(DFS.DFSanCheckedUnionFn, {PV1, PV2});
|
||||
Call->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
Call->addParamAttr(0, Attribute::ZExt);
|
||||
Call->addParamAttr(1, Attribute::ZExt);
|
||||
|
||||
CCS.Block = Pos->getParent();
|
||||
CCS.Shadow = Call;
|
||||
} else {
|
||||
BasicBlock *Head = Pos->getParent();
|
||||
Value *Ne = IRB.CreateICmpNE(PV1, PV2);
|
||||
BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen(
|
||||
Ne, Pos, /*Unreachable=*/false, DFS.ColdCallWeights, &DT));
|
||||
IRBuilder<> ThenIRB(BI);
|
||||
CallInst *Call = ThenIRB.CreateCall(DFS.DFSanUnionFn, {PV1, PV2});
|
||||
Call->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
Call->addParamAttr(0, Attribute::ZExt);
|
||||
Call->addParamAttr(1, Attribute::ZExt);
|
||||
|
||||
BasicBlock *Tail = BI->getSuccessor(0);
|
||||
PHINode *Phi =
|
||||
PHINode::Create(DFS.PrimitiveShadowTy, 2, "", &Tail->front());
|
||||
Phi->addIncoming(Call, Call->getParent());
|
||||
Phi->addIncoming(PV1, Head);
|
||||
|
||||
CCS.Block = Tail;
|
||||
CCS.Shadow = Phi;
|
||||
}
|
||||
|
||||
std::set<Value *> UnionElems;
|
||||
if (V1Elems != ShadowElements.end()) {
|
||||
|
@ -2116,7 +1963,7 @@ Value *DataFlowSanitizer::loadNextOrigin(Instruction *Pos, Align OriginAlign,
|
|||
return IRB.CreateAlignedLoad(OriginTy, *OriginAddr, OriginAlign);
|
||||
}
|
||||
|
||||
std::pair<Value *, Value *> DFSanFunction::loadFast16ShadowFast(
|
||||
std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
|
||||
Value *ShadowAddr, Value *OriginAddr, uint64_t Size, Align ShadowAlign,
|
||||
Align OriginAlign, Value *FirstOrigin, Instruction *Pos) {
|
||||
const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
|
||||
|
@ -2135,7 +1982,7 @@ std::pair<Value *, Value *> DFSanFunction::loadFast16ShadowFast(
|
|||
// Specifically, when the shadow size in bytes (i.e., loaded bytes x shadow
|
||||
// per byte) is either:
|
||||
// - a multiple of 8 (common)
|
||||
// - equal to 4 (only for load32 in fast-8 mode)
|
||||
// - equal to 4 (only for load32)
|
||||
//
|
||||
// For the second case, we can fit the wide shadow in a 32-bit integer. In all
|
||||
// other cases, we use a 64-bit integer to hold the wide shadow.
|
||||
|
@ -2204,84 +2051,6 @@ std::pair<Value *, Value *> DFSanFunction::loadFast16ShadowFast(
|
|||
: DFS.ZeroOrigin};
|
||||
}
|
||||
|
||||
Value *DFSanFunction::loadLegacyShadowFast(Value *ShadowAddr, uint64_t Size,
|
||||
Align ShadowAlign,
|
||||
Instruction *Pos) {
|
||||
// Fast path for the common case where each byte has identical shadow: load
|
||||
// shadow 64 (or 32) bits at a time, fall out to a __dfsan_union_load call if
|
||||
// any shadow is non-equal.
|
||||
BasicBlock *FallbackBB = BasicBlock::Create(*DFS.Ctx, "", F);
|
||||
IRBuilder<> FallbackIRB(FallbackBB);
|
||||
CallInst *FallbackCall = FallbackIRB.CreateCall(
|
||||
DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
|
||||
FallbackCall->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
|
||||
const uint64_t ShadowSize = Size * DFS.ShadowWidthBytes;
|
||||
assert(Size >= 4 && "Not large enough load size for fast path!");
|
||||
|
||||
// Same as in loadFast16AShadowsFast. In the case of load32, we can fit the
|
||||
// wide shadow in a 32-bit integer instead.
|
||||
Type *WideShadowTy =
|
||||
ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) : Type::getInt64Ty(*DFS.Ctx);
|
||||
|
||||
// Compare each of the shadows stored in the loaded 64 bits to each other,
|
||||
// by computing (WideShadow rotl ShadowWidthBits) == WideShadow.
|
||||
IRBuilder<> IRB(Pos);
|
||||
unsigned WideShadowBitWidth = WideShadowTy->getIntegerBitWidth();
|
||||
Value *WideAddr = IRB.CreateBitCast(ShadowAddr, WideShadowTy->getPointerTo());
|
||||
Value *WideShadow =
|
||||
IRB.CreateAlignedLoad(WideShadowTy, WideAddr, ShadowAlign);
|
||||
Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.PrimitiveShadowTy);
|
||||
Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidthBits);
|
||||
Value *ShrShadow =
|
||||
IRB.CreateLShr(WideShadow, WideShadowBitWidth - DFS.ShadowWidthBits);
|
||||
Value *RotShadow = IRB.CreateOr(ShlShadow, ShrShadow);
|
||||
Value *ShadowsEq = IRB.CreateICmpEQ(WideShadow, RotShadow);
|
||||
|
||||
BasicBlock *Head = Pos->getParent();
|
||||
BasicBlock *Tail = Head->splitBasicBlock(Pos->getIterator());
|
||||
|
||||
if (DomTreeNode *OldNode = DT.getNode(Head)) {
|
||||
std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
|
||||
|
||||
DomTreeNode *NewNode = DT.addNewBlock(Tail, Head);
|
||||
for (auto *Child : Children)
|
||||
DT.changeImmediateDominator(Child, NewNode);
|
||||
}
|
||||
|
||||
// In the following code LastBr will refer to the previous basic block's
|
||||
// conditional branch instruction, whose true successor is fixed up to point
|
||||
// to the next block during the loop below or to the tail after the final
|
||||
// iteration.
|
||||
BranchInst *LastBr = BranchInst::Create(FallbackBB, FallbackBB, ShadowsEq);
|
||||
ReplaceInstWithInst(Head->getTerminator(), LastBr);
|
||||
DT.addNewBlock(FallbackBB, Head);
|
||||
|
||||
const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
|
||||
|
||||
for (uint64_t ByteOfs = BytesPerWideShadow; ByteOfs < Size;
|
||||
ByteOfs += BytesPerWideShadow) {
|
||||
BasicBlock *NextBB = BasicBlock::Create(*DFS.Ctx, "", F);
|
||||
DT.addNewBlock(NextBB, LastBr->getParent());
|
||||
IRBuilder<> NextIRB(NextBB);
|
||||
WideAddr = NextIRB.CreateGEP(WideShadowTy, WideAddr,
|
||||
ConstantInt::get(DFS.IntptrTy, 1));
|
||||
Value *NextWideShadow =
|
||||
NextIRB.CreateAlignedLoad(WideShadowTy, WideAddr, ShadowAlign);
|
||||
ShadowsEq = NextIRB.CreateICmpEQ(WideShadow, NextWideShadow);
|
||||
LastBr->setSuccessor(0, NextBB);
|
||||
LastBr = NextIRB.CreateCondBr(ShadowsEq, FallbackBB, FallbackBB);
|
||||
}
|
||||
|
||||
LastBr->setSuccessor(0, Tail);
|
||||
FallbackIRB.CreateBr(Tail);
|
||||
PHINode *Shadow =
|
||||
PHINode::Create(DFS.PrimitiveShadowTy, 2, "", &Tail->front());
|
||||
Shadow->addIncoming(FallbackCall, FallbackBB);
|
||||
Shadow->addIncoming(TruncShadow, LastBr->getParent());
|
||||
return Shadow;
|
||||
}
|
||||
|
||||
std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
|
||||
Value *Addr, uint64_t Size, Align InstAlignment, Instruction *Pos) {
|
||||
const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
|
||||
|
@ -2369,21 +2138,14 @@ std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
|
|||
}
|
||||
}
|
||||
bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(Size);
|
||||
bool HasFastLabelsEnabled = DFS.hasFastLabelsEnabled();
|
||||
|
||||
if (HasFastLabelsEnabled && HasSizeForFastPath)
|
||||
return loadFast16ShadowFast(ShadowAddr, OriginAddr, Size, ShadowAlign,
|
||||
if (HasSizeForFastPath)
|
||||
return loadShadowFast(ShadowAddr, OriginAddr, Size, ShadowAlign,
|
||||
OriginAlign, Origin, Pos);
|
||||
|
||||
if (!AvoidNewBlocks && HasSizeForFastPath)
|
||||
return {loadLegacyShadowFast(ShadowAddr, Size, ShadowAlign, Pos), Origin};
|
||||
|
||||
IRBuilder<> IRB(Pos);
|
||||
FunctionCallee &UnionLoadFn = HasFastLabelsEnabled
|
||||
? DFS.DFSanUnionLoadFastLabelsFn
|
||||
: DFS.DFSanUnionLoadFn;
|
||||
CallInst *FallbackCall = IRB.CreateCall(
|
||||
UnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
|
||||
DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
|
||||
FallbackCall->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt);
|
||||
return {FallbackCall, Origin};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-args-abi -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-args-abi -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-args-abi -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI
|
||||
; RUN: opt < %s -dfsan -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s --check-prefixes=CHECK,LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI
|
||||
; RUN: opt < %s -dfsan -dfsan-args-abi -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s --check-prefixes=CHECK,ARGS_ABI
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
@ -33,19 +31,12 @@ define {i1, i7} @call_functional({i32, i1} %a, [2 x i7] %b) {
|
|||
; TLS_ABI-NEXT: %[[#REG+10]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } %[[#REG+9]], i[[#SBITS]] %[[#REG+8]], 1
|
||||
; TLS_ABI: store { i[[#SBITS]], i[[#SBITS]] } %[[#REG+10]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
|
||||
; LEGACY: @"dfs$call_functional"
|
||||
; LEGACY: [[B:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[A:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[A]], i[[#SBITS]] zeroext [[B]])
|
||||
; LEGACY: [[PH:%.*]] = phi i[[#SBITS]] [ [[U]], {{.*}} ], [ [[A]], {{.*}} ]
|
||||
; LEGACY: store i[[#SBITS]] [[PH]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; ARGS_ABI: @"dfs$call_functional"
|
||||
; ARGS_ABI: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext %2, i[[#SBITS]] zeroext %3)
|
||||
; ARGS_ABI: [[PH:%.*]] = phi i[[#SBITS]] [ %7, {{.*}} ], [ %2, {{.*}} ]
|
||||
; ARGS_ABI: [[R0:%.*]] = insertvalue { { i1, i7 }, i[[#SBITS]] } undef, { i1, i7 } %r, 0
|
||||
; ARGS_ABI: [[R1:%.*]] = insertvalue { { i1, i7 }, i[[#SBITS]] } [[R0]], i[[#SBITS]] [[PH]], 1
|
||||
; ARGS_ABI: ret { { i1, i7 }, i[[#SBITS]] } [[R1]]
|
||||
; ARGS_ABI: @"dfs$call_functional"({ i32, i1 } %0, [2 x i7] %1, i[[#SBITS]] %2, i[[#SBITS]] %3)
|
||||
; ARGS_ABI: %[[#U:]] = or i[[#SBITS]] %2, %3
|
||||
; ARGS_ABI: %r = call { i1, i7 } @functional({ i32, i1 } %0, [2 x i7] %1)
|
||||
; ARGS_ABI: %[[#R:]] = insertvalue { { i1, i7 }, i[[#SBITS]] } undef, { i1, i7 } %r, 0
|
||||
; ARGS_ABI: %[[#R+1]] = insertvalue { { i1, i7 }, i[[#SBITS]] } %[[#R]], i[[#SBITS]] %[[#U]], 1
|
||||
; ARGS_ABI: ret { { i1, i7 }, i[[#SBITS]] } %[[#R+1]]
|
||||
|
||||
%r = call {i1, i7} @functional({i32, i1} %a, [2 x i7] %b)
|
||||
ret {i1, i7} %r
|
||||
|
|
|
@ -7,13 +7,12 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||
|
||||
define i8 @add(i8 %a, i8 %b) {
|
||||
; CHECK: @"dfs$add"
|
||||
; CHECK-DAG: %[[ALABEL:.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; CHECK-DAG: %[[BLABEL:.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: %[[UNION:.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext %[[ALABEL]], i[[#SBITS]] zeroext %[[BLABEL]])
|
||||
; CHECK: %[[ADDLABEL:.*]] = phi i[[#SBITS]] [ %[[UNION]], {{.*}} ], [ %[[ALABEL]], {{.*}} ]
|
||||
; CHECK: add i8
|
||||
; CHECK: store i[[#SBITS]] %[[ADDLABEL]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: ret i8
|
||||
; CHECK-DAG: %[[#ALABEL:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; CHECK-DAG: %[[#BLABEL:]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: %[[#UNION:]] = or i[[#SBITS]] %[[#ALABEL]], %[[#BLABEL]]
|
||||
; CHECK: %c = add i8 %a, %b
|
||||
; CHECK: store i[[#SBITS]] %[[#UNION]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: ret i8 %c
|
||||
%c = add i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
@ -22,10 +21,10 @@ define i8 @sub(i8 %a, i8 %b) {
|
|||
; CHECK: @"dfs$sub"
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: sub i8
|
||||
; CHECK: or i[[#SBITS]]
|
||||
; CHECK: %c = sub i8 %a, %b
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
; CHECK: ret i8 %c
|
||||
%c = sub i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
@ -34,10 +33,10 @@ define i8 @mul(i8 %a, i8 %b) {
|
|||
; CHECK: @"dfs$mul"
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: mul i8
|
||||
; CHECK: or i[[#SBITS]]
|
||||
; CHECK: %c = mul i8 %a, %b
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
; CHECK: ret i8 %c
|
||||
%c = mul i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
@ -46,10 +45,10 @@ define i8 @sdiv(i8 %a, i8 %b) {
|
|||
; CHECK: @"dfs$sdiv"
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: sdiv i8
|
||||
; CHECK: or i[[#SBITS]]
|
||||
; CHECK: %c = sdiv i8 %a, %b
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
; CHECK: ret i8 %c
|
||||
%c = sdiv i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
@ -58,10 +57,10 @@ define i8 @udiv(i8 %a, i8 %b) {
|
|||
; CHECK: @"dfs$udiv"
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: udiv i8
|
||||
; CHECK: or i[[#SBITS]]
|
||||
; CHECK: %c = udiv i8 %a, %b
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret i8
|
||||
; CHECK: ret i8 %c
|
||||
%c = udiv i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
@ -69,9 +68,9 @@ define i8 @udiv(i8 %a, i8 %b) {
|
|||
define double @fneg(double %a) {
|
||||
; CHECK: @"dfs$fneg"
|
||||
; CHECK: load{{.*}}__dfsan_arg_tls
|
||||
; CHECK: fneg double
|
||||
; CHECK: %c = fneg double %a
|
||||
; CHECK: store{{.*}}__dfsan_retval_tls
|
||||
; CHECK: ret double
|
||||
; CHECK: ret double %c
|
||||
%c = fneg double %a
|
||||
ret double %c
|
||||
}
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS
|
||||
; RUN: opt < %s -dfsan -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS
|
||||
; RUN: opt < %s -dfsan -dfsan-args-abi -S | FileCheck %s --check-prefixes=CHECK,ARGS_ABI
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -102,13 +96,6 @@ define [1 x i1] @load_array1([1 x i1]* %p) {
|
|||
; FAST: [[S1:%.*]] = insertvalue [1 x i[[#SBITS]]] undef, i[[#SBITS]] [[U]], 0
|
||||
; FAST: store [1 x i[[#SBITS]]] [[S1]], [1 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [1 x i[[#SBITS]]]*), align [[ALIGN]]
|
||||
|
||||
; LEGACY: @"dfs$load_array1"
|
||||
; LEGACY: [[P:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[L:%.*]] = load i[[#SBITS]], i[[#SBITS]]* {{.*}}, align [[#SBYTES]]
|
||||
; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[L]], i[[#SBITS]] zeroext [[P]])
|
||||
; LEGACY: [[PH:%.*]] = phi i[[#SBITS]] [ [[U]], {{.*}} ], [ [[L]], {{.*}} ]
|
||||
; LEGACY: store i[[#SBITS]] [[PH]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
%a = load [1 x i1], [1 x i1]* %p
|
||||
ret [1 x i1] %a
|
||||
}
|
||||
|
@ -164,13 +151,6 @@ define [4 x i1] @load_array4([4 x i1]* %p) {
|
|||
; FAST: [[S4:%.*]] = insertvalue [4 x i[[#SBITS]]] [[S3]], i[[#SBITS]] [[O]], 3
|
||||
; FAST: store [4 x i[[#SBITS]]] [[S4]], [4 x i[[#SBITS]]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to [4 x i[[#SBITS]]]*), align 2
|
||||
|
||||
; LEGACY: @"dfs$load_array4"
|
||||
; LEGACY: [[P:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[PH1:%.*]] = phi i[[#SBITS]]
|
||||
; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[PH1]], i[[#SBITS]] zeroext [[P]])
|
||||
; LEGACY: [[PH:%.*]] = phi i[[#SBITS]] [ [[U]], {{.*}} ], [ [[PH1]], {{.*}} ]
|
||||
; LEGACY: store i[[#SBITS]] [[PH]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
%a = load [4 x i1], [4 x i1]* %p
|
||||
ret [4 x i1] %a
|
||||
}
|
||||
|
@ -220,13 +200,6 @@ define void @store_zero_array([4 x i1]* %p) {
|
|||
}
|
||||
|
||||
define void @store_array2([2 x i1] %a, [2 x i1]* %p) {
|
||||
; LEGACY: @"dfs$store_array2"
|
||||
; LEGACY: [[S:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[SP0:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[SP:%.*]], i32 0
|
||||
; LEGACY: store i[[#SBITS]] [[S]], i[[#SBITS]]* [[SP0]], align [[#SBYTES]]
|
||||
; LEGACY: [[SP1:%.*]] = getelementptr i[[#SBITS]], i[[#SBITS]]* [[SP]], i32 1
|
||||
; LEGACY: store i[[#SBITS]] [[S]], i[[#SBITS]]* [[SP1]], align [[#SBYTES]]
|
||||
|
||||
; EVENT_CALLBACKS: @"dfs$store_array2"
|
||||
; EVENT_CALLBACKS: [[E12:%.*]] = or i[[#SBITS]]
|
||||
; EVENT_CALLBACKS: [[P:%.*]] = bitcast [2 x i1]* %p to i8*
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK16
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK16,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK16,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -21,7 +18,6 @@ entry:
|
|||
; CHECK-NOT: @__dfsan_arg_tls
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -42,7 +38,6 @@ define i32 @AtomicRmwMax(i32* %p, i32 %x) {
|
|||
; CHECK-NOT: @__dfsan_arg_tls
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -65,7 +60,6 @@ define i32 @Cmpxchg(i32* %p, i32 %a, i32 %b) {
|
|||
; CHECK-NOT: @__dfsan_arg_tls
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -89,7 +83,6 @@ define i32 @CmpxchgMonotonic(i32* %p, i32 %a, i32 %b) {
|
|||
; CHECK-NOT: @__dfsan_arg_tls
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -213,7 +206,6 @@ define void @AtomicStore(i32* %p, i32 %x) {
|
|||
; CHECK_ORIGIN-NOT: 35184372088832
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -234,7 +226,6 @@ define void @AtomicStoreRelease(i32* %p, i32 %x) {
|
|||
; CHECK_ORIGIN-NOT: 35184372088832
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -255,7 +246,6 @@ define void @AtomicStoreMonotonic(i32* %p, i32 %x) {
|
|||
; CHECK_ORIGIN-NOT: 35184372088832
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
@ -276,7 +266,6 @@ define void @AtomicStoreUnordered(i32* %p, i32 %x) {
|
|||
; CHECK_ORIGIN-NOT: 35184372088832
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:INTP+2]] = mul i64 %[[#INTP+1]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR64:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#NUM_BITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: store i[[#NUM_BITS]] 0, i[[#NUM_BITS]]* %[[#SHADOW_PTR64]], align [[#SBYTES]]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,CHECK_NO_ORIGIN -DSHADOW_MASK=-123145302310913
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN -DSHADOW_MASK=-123145302310913
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN -DSHADOW_MASK=-105553116266497
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,CHECK_NO_ORIGIN -DSHADOW_MASK=-105553116266497 --dump-input-context=100
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN -DSHADOW_MASK=-105553116266497 --dump-input-context=100
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -35,20 +34,11 @@ define void @store(i8* %p) {
|
|||
; CHECK: declare void @__dfsan_mem_transfer_callback(i[[#SBITS]]*, i64)
|
||||
; CHECK: declare void @__dfsan_cmp_callback(i[[#SBITS]])
|
||||
|
||||
; CHECK: ; Function Attrs: nounwind readnone
|
||||
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext, i[[#SBITS]] zeroext) #0
|
||||
|
||||
; CHECK: ; Function Attrs: nounwind readnone
|
||||
; CHECK-NEXT: declare zeroext i[[#SBITS]] @dfsan_union(i[[#SBITS]] zeroext, i[[#SBITS]] zeroext) #0
|
||||
; CHECK: ; Function Attrs: nounwind readonly
|
||||
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load(i[[#SBITS]]*, i64)
|
||||
|
||||
; CHECK: ; Function Attrs: nounwind readonly
|
||||
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load(i[[#SBITS]]*, i64) #1
|
||||
|
||||
; CHECK: ; Function Attrs: nounwind readonly
|
||||
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load_fast16labels(i[[#SBITS]]*, i64) #1
|
||||
|
||||
; CHECK: ; Function Attrs: nounwind readonly
|
||||
; CHECK-NEXT: declare zeroext i64 @__dfsan_load_label_and_origin(i8*, i64) #1
|
||||
; CHECK-NEXT: declare zeroext i64 @__dfsan_load_label_and_origin(i8*, i64)
|
||||
|
||||
; CHECK: declare void @__dfsan_unimplemented(i8*)
|
||||
; CHECK: declare void @__dfsan_set_label(i[[#SBITS]] zeroext, i32 zeroext, i8*, i64)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -passes=dfsan -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-combine-offset-labels-on-gep=false -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-offset-labels-on-gep=false -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,CHECK16
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,CHECK16
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
define i32 @test(i32 %a, i32* nocapture readonly %b) #0 {
|
||||
; CHECK: @"dfs$test"
|
||||
; CHECK: %[[RV:.*]] load{{.*}}__dfsan_shadow_ptr_mask
|
||||
; CHECK: ptrtoint i32* {{.*}} to i64
|
||||
; CHECK: and {{.*}}%[[RV:.*]]
|
||||
; CHECK16: mul i64
|
||||
; CHECK: @"dfs$test"
|
||||
; CHECK: %[[RV:.*]] load{{.*}}__dfsan_shadow_ptr_mask
|
||||
; CHECK: ptrtoint i32* {{.*}} to i64
|
||||
; CHECK: and {{.*}}%[[RV:.*]]
|
||||
%1 = load i32, i32* %b, align 4
|
||||
%2 = add nsw i32 %1, %a
|
||||
ret i32 %2
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
; Test that -dfsan-fast-16-labels mode uses inline ORs rather than calling
|
||||
; __dfsan_union or __dfsan_union_load.
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -S | FileCheck %s --implicit-check-not="call{{.*}}__dfsan_union" --check-prefixes=CHECK,CHECK16
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -S | FileCheck %s --implicit-check-not="call{{.*}}__dfsan_union" --check-prefixes=CHECK,CHECK8
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
|
||||
; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
|
||||
; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]]
|
||||
; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]
|
||||
|
||||
define i8 @add(i8 %a, i8 %b) {
|
||||
; CHECK-LABEL: define i8 @"dfs$add"
|
||||
; CHECK-DAG: %[[ALABEL:.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; CHECK-DAG: %[[BLABEL:.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: %[[ADDLABEL:.*]] = or i[[#SBITS]] %[[ALABEL]], %[[BLABEL]]
|
||||
; CHECK: %c = add i8 %a, %b
|
||||
; CHECK: store i[[#SBITS]] %[[ADDLABEL]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: ret i8 %c
|
||||
%c = add i8 %a, %b
|
||||
ret i8 %c
|
||||
}
|
||||
|
||||
define i8 @load8(i8* %p) {
|
||||
; CHECK-LABEL: define i8 @"dfs$load8"
|
||||
; CHECK-SAME: (i8* %[[PADDR:.*]])
|
||||
; CHECK-NEXT: %[[#ARG:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#R:]] = ptrtoint i8* %[[PADDR]] to i64
|
||||
; CHECK-NEXT: %[[#PS:R+1]] = and i64 %[[#R]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#PS:R+2]] = mul i64 %[[#R+1]], 2
|
||||
; CHECK-NEXT: %[[#SADDR:]] = inttoptr i64 %[[#PS]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#S:]] = load i[[#SBITS]], i[[#SBITS]]* %[[#SADDR]]
|
||||
; CHECK-NEXT: %[[#S_OUT:S+1]] = or i[[#SBITS]] %[[#S]], %[[#ARG]]
|
||||
; CHECK-NEXT: %a = load i8, i8* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#S_OUT]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i8 %a
|
||||
|
||||
%a = load i8, i8* %p
|
||||
ret i8 %a
|
||||
}
|
||||
|
||||
define i16 @load16(i16* %p) {
|
||||
; CHECK-LABEL: define i16 @"dfs$load16"
|
||||
; CHECK-SAME: (i16* %[[PADDR:.*]])
|
||||
; CHECK-NEXT: %[[#ARG:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#R:]] = ptrtoint i16* %[[PADDR]] to i64
|
||||
; CHECK-NEXT: %[[#PS:R+1]] = and i64 %[[#R]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#PS:R+2]] = mul i64 %[[#R+1]], 2
|
||||
; CHECK-NEXT: %[[#SADDR:]] = inttoptr i64 %[[#PS]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SADDR+1]] = getelementptr i[[#SBITS]], i[[#SBITS]]* %[[#SADDR]], i64 1
|
||||
; CHECK-NEXT: %[[#S:]] = load i[[#SBITS]], i[[#SBITS]]* %[[#SADDR]]
|
||||
; CHECK-NEXT: %[[#S+1]] = load i[[#SBITS]], i[[#SBITS]]* %[[#SADDR+1]]
|
||||
; CHECK-NEXT: %[[#S+2]] = or i[[#SBITS]] %[[#S]], %[[#S+1]]
|
||||
; CHECK-NEXT: %[[#S_OUT:S+3]] = or i[[#SBITS]] %[[#S+2]], %[[#ARG]]
|
||||
; CHECK-NEXT: %a = load i16, i16* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#S_OUT]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i16 %a
|
||||
|
||||
%a = load i16, i16* %p
|
||||
ret i16 %a
|
||||
}
|
||||
|
||||
define i32 @load32(i32* %p) {
|
||||
; CHECK-LABEL: define i32 @"dfs$load32"
|
||||
; CHECK-SAME: (i32* %[[PADDR:.*]])
|
||||
; CHECK-NEXT: %[[#ARG:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#R:]] = ptrtoint i32* %[[PADDR]] to i64
|
||||
; CHECK-NEXT: %[[#PS:R+1]] = and i64 %[[#R]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#PS:R+2]] = mul i64 %[[#R+1]], 2
|
||||
; CHECK-NEXT: %[[#SADDR:]] = inttoptr i64 %[[#PS]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SADDR+1]] = bitcast i[[#SBITS]]* %[[#SADDR]] to i[[#WBITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: %[[#WS:]] = load i[[#WBITS]], i[[#WBITS]]* %[[#SADDR+1]]
|
||||
; CHECK-NEXT: %[[#WS+1]] = lshr i[[#WBITS]] %[[#WS]], [[#mul(SBITS,2)]]
|
||||
; CHECK-NEXT: %[[#WS+2]] = or i[[#WBITS]] %[[#WS]], %[[#WS+1]]
|
||||
; CHECK-NEXT: %[[#WS+3]] = lshr i[[#WBITS]] %[[#WS+2]], [[#SBITS]]
|
||||
; CHECK-NEXT: %[[#WS+4]] = or i[[#WBITS]] %[[#WS+2]], %[[#WS+3]]
|
||||
; CHECK-NEXT: %[[#WS+5]] = trunc i[[#WBITS]] %[[#WS+4]] to i[[#SBITS]]
|
||||
; CHECK-NEXT: %[[#S_OUT:WS+6]] = or i[[#SBITS]] %[[#WS+5]], %[[#ARG]]
|
||||
; CHECK-NEXT: %a = load i32, i32* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#S_OUT]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i32 %a
|
||||
|
||||
%a = load i32, i32* %p
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
define i64 @load64(i64* %p) {
|
||||
; CHECK-LABEL: define i64 @"dfs$load64"
|
||||
; CHECK-SAME: (i64* %[[PADDR:.*]])
|
||||
; CHECK-NEXT: %[[#ARG:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#R:]] = ptrtoint i64* %[[PADDR]] to i64
|
||||
; CHECK-NEXT: %[[#PS:R+1]] = and i64 %[[#R]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#PS:R+2]] = mul i64 %[[#R+1]], 2
|
||||
; CHECK-NEXT: %[[#SADDR:]] = inttoptr i64 %[[#PS]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SADDR+1]] = bitcast i[[#SBITS]]* %[[#SADDR]] to i64*
|
||||
; CHECK-NEXT: %[[#WS:]] = load i64, i64* %[[#SADDR+1]]
|
||||
|
||||
; COMM: On fast16, the 2x64 shadow bits need to be ORed first.
|
||||
; CHECK16-NEXT: %[[#SADDR_NEXT:]] = getelementptr i64, i64* %[[#SADDR+1]], i64 1
|
||||
; CHECK16-NEXT: %[[#WS_NEXT:]] = load i64, i64* %[[#SADDR_NEXT]]
|
||||
; CHECK16-NEXT: %[[#WS:]] = or i64 %[[#WS]], %[[#WS_NEXT]]
|
||||
; CHECK16-NEXT: %[[#WS+1]] = lshr i64 %[[#WS]], 32
|
||||
; CHECK16-NEXT: %[[#WS+2]] = or i64 %[[#WS]], %[[#WS+1]]
|
||||
; CHECK16-NEXT: %[[#WS+3]] = lshr i64 %[[#WS+2]], 16
|
||||
; CHECK16-NEXT: %[[#WS+4]] = or i64 %[[#WS+2]], %[[#WS+3]]
|
||||
; CHECK16-NEXT: %[[#WS+5]] = trunc i64 %[[#WS+4]] to i[[#SBITS]]
|
||||
; CHECK16-NEXT: %[[#S_OUT:]] = or i[[#SBITS]] %[[#WS+5]], %[[#ARG]]
|
||||
|
||||
; COMM: On fast8, no need to OR the wide shadow but one more shift is needed.
|
||||
; CHECK8-NEXT: %[[#WS+1]] = lshr i64 %[[#WS]], 32
|
||||
; CHECK8-NEXT: %[[#WS+2]] = or i64 %[[#WS]], %[[#WS+1]]
|
||||
; CHECK8-NEXT: %[[#WS+3]] = lshr i64 %[[#WS+2]], 16
|
||||
; CHECK8-NEXT: %[[#WS+4]] = or i64 %[[#WS+2]], %[[#WS+3]]
|
||||
; CHECK8-NEXT: %[[#WS+5]] = lshr i64 %[[#WS+4]], 8
|
||||
; CHECK8-NEXT: %[[#WS+6]] = or i64 %[[#WS+4]], %[[#WS+5]]
|
||||
; CHECK8-NEXT: %[[#WS+7]] = trunc i64 %[[#WS+6]] to i[[#SBITS]]
|
||||
; CHECK8-NEXT: %[[#S_OUT:]] = or i[[#SBITS]] %[[#WS+7]], %[[#ARG]]
|
||||
|
||||
; CHECK-NEXT: %a = load i64, i64* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#S_OUT]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i64 %a
|
||||
|
||||
%a = load i64, i64* %p
|
||||
ret i64 %a
|
||||
}
|
||||
|
||||
define i128 @load128(i128* %p) {
|
||||
; CHECK-LABEL: define i128 @"dfs$load128"
|
||||
; CHECK-SAME: (i128* %[[PADDR:.*]])
|
||||
; CHECK-NEXT: %[[#ARG:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#R:]] = ptrtoint i128* %[[PADDR]] to i64
|
||||
; CHECK-NEXT: %[[#PS:R+1]] = and i64 %[[#R]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#PS:R+2]] = mul i64 %[[#R+1]], 2
|
||||
; CHECK-NEXT: %[[#SADDR:]] = inttoptr i64 %[[#PS]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SADDR+1]] = bitcast i[[#SBITS]]* %[[#SADDR]] to i64*
|
||||
; CHECK-NEXT: %[[#S:]] = load i64, i64* %[[#SADDR+1]]
|
||||
; CHECK-NEXT: %[[#S+1]] = getelementptr i64, i64* %[[#SADDR+1]], i64 1
|
||||
; CHECK-NEXT: %[[#S+2]] = load i64, i64* %[[#S+1]]
|
||||
; CHECK-NEXT: %[[#WS:S+3]] = or i64 %[[#S]], %[[#S+2]]
|
||||
|
||||
; COMM: On fast16, we need to OR 4x64bits for the wide shadow, before ORing its bytes.
|
||||
; CHECK16-NEXT: %[[#S+4]] = getelementptr i64, i64* %[[#S+1]], i64 1
|
||||
; CHECK16-NEXT: %[[#S+5]] = load i64, i64* %[[#S+4]]
|
||||
; CHECK16-NEXT: %[[#S+6]] = or i64 %[[#S+3]], %[[#S+5]]
|
||||
; CHECK16-NEXT: %[[#S+7]] = getelementptr i64, i64* %[[#S+4]], i64 1
|
||||
; CHECK16-NEXT: %[[#S+8]] = load i64, i64* %[[#S+7]]
|
||||
; CHECK16-NEXT: %[[#WS:S+9]] = or i64 %[[#S+6]], %[[#S+8]]
|
||||
; CHECK16-NEXT: %[[#WS+1]] = lshr i64 %[[#WS]], 32
|
||||
; CHECK16-NEXT: %[[#WS+2]] = or i64 %[[#WS]], %[[#WS+1]]
|
||||
; CHECK16-NEXT: %[[#WS+3]] = lshr i64 %[[#WS+2]], 16
|
||||
; CHECK16-NEXT: %[[#WS+4]] = or i64 %[[#WS+2]], %[[#WS+3]]
|
||||
; CHECK16-NEXT: %[[#WS+5]] = trunc i64 %[[#WS+4]] to i[[#SBITS]]
|
||||
; CHECK16-NEXT: %[[#S_OUT:]] = or i[[#SBITS]] %[[#WS+5]], %[[#ARG]]
|
||||
|
||||
; COMM: On fast8, we need to OR 2x64bits for the wide shadow, before ORing its bytes (one more shift).
|
||||
; CHECK8-NEXT: %[[#WS+1]] = lshr i64 %[[#WS]], 32
|
||||
; CHECK8-NEXT: %[[#WS+2]] = or i64 %[[#WS]], %[[#WS+1]]
|
||||
; CHECK8-NEXT: %[[#WS+3]] = lshr i64 %[[#WS+2]], 16
|
||||
; CHECK8-NEXT: %[[#WS+4]] = or i64 %[[#WS+2]], %[[#WS+3]]
|
||||
; CHECK8-NEXT: %[[#WS+5]] = lshr i64 %[[#WS+4]], 8
|
||||
; CHECK8-NEXT: %[[#WS+6]] = or i64 %[[#WS+4]], %[[#WS+5]]
|
||||
; CHECK8-NEXT: %[[#WS+7]] = trunc i64 %[[#WS+6]] to i[[#SBITS]]
|
||||
; CHECK8-NEXT: %[[#S_OUT:]] = or i[[#SBITS]] %[[#WS+7]], %[[#ARG]]
|
||||
|
||||
; CHECK-NEXT: %a = load i128, i128* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#S_OUT]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i128 %a
|
||||
|
||||
%a = load i128, i128* %p
|
||||
ret i128 %a
|
||||
}
|
|
@ -1,176 +1,156 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=1 -S | FileCheck %s --check-prefix=COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=0 -S | FileCheck %s --check-prefix=NO_COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define {} @load0({}* %p) {
|
||||
; COMBINE_PTR_LABEL: @"dfs$load0"
|
||||
; COMBINE_PTR_LABEL: load
|
||||
; COMBINE_PTR_LABEL-NOT: load
|
||||
; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
|
||||
; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
|
||||
; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]]
|
||||
; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]
|
||||
|
||||
|
||||
define {} @load0({}* %p) {
|
||||
; CHECK-LABEL: @"dfs$load0"
|
||||
; CHECK-NEXT: %a = load {}, {}* %p, align 1
|
||||
; CHECK-NEXT: store {} zeroinitializer, {}* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to {}*), align [[ALIGN:2]]
|
||||
; CHECK-NEXT: ret {} %a
|
||||
|
||||
; NO_COMBINE_PTR_LABEL: @"dfs$load0"
|
||||
; NO_COMBINE_PTR_LABEL: load
|
||||
; NO_COMBINE_PTR_LABEL-NOT: load
|
||||
%a = load {}, {}* %p
|
||||
ret {} %a
|
||||
}
|
||||
|
||||
define i8 @load8(i8* %p) {
|
||||
; COMBINE_PTR_LABEL: @"dfs$load8"
|
||||
; COMBINE_PTR_LABEL: load i16, i16*
|
||||
; COMBINE_PTR_LABEL: ptrtoint i8* {{.*}} to i64
|
||||
; COMBINE_PTR_LABEL: and i64
|
||||
; COMBINE_PTR_LABEL: mul i64
|
||||
; COMBINE_PTR_LABEL: inttoptr i64
|
||||
; COMBINE_PTR_LABEL: load i16, i16*
|
||||
; COMBINE_PTR_LABEL: icmp ne i16
|
||||
; COMBINE_PTR_LABEL: call zeroext i16 @__dfsan_union
|
||||
; COMBINE_PTR_LABEL: load i8, i8*
|
||||
; COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; COMBINE_PTR_LABEL: ret i8
|
||||
|
||||
; NO_COMBINE_PTR_LABEL: @"dfs$load8"
|
||||
; NO_COMBINE_PTR_LABEL: ptrtoint i8*
|
||||
; NO_COMBINE_PTR_LABEL: and i64
|
||||
; NO_COMBINE_PTR_LABEL: mul i64
|
||||
; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} to i16*
|
||||
; NO_COMBINE_PTR_LABEL: load i16, i16*
|
||||
; NO_COMBINE_PTR_LABEL: load i8, i8*
|
||||
; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; NO_COMBINE_PTR_LABEL: ret i8
|
||||
; CHECK-LABEL: @"dfs$load8"
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i8* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = load i[[#SBITS]], i[[#SBITS]]* %[[#SHADOW_PTR]]
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; CHECK-NEXT: %a = load i8, i8* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#SHADOW]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i8 %a
|
||||
|
||||
%a = load i8, i8* %p
|
||||
ret i8 %a
|
||||
}
|
||||
|
||||
define i16 @load16(i16* %p) {
|
||||
; COMBINE_PTR_LABEL: @"dfs$load16"
|
||||
; COMBINE_PTR_LABEL: ptrtoint i16*
|
||||
; COMBINE_PTR_LABEL: and i64
|
||||
; COMBINE_PTR_LABEL: mul i64
|
||||
; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
|
||||
; COMBINE_PTR_LABEL: getelementptr i16
|
||||
; COMBINE_PTR_LABEL: load i16, i16*
|
||||
; COMBINE_PTR_LABEL: load i16, i16*
|
||||
; COMBINE_PTR_LABEL: icmp ne
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
; COMBINE_PTR_LABEL: icmp ne i16
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
; COMBINE_PTR_LABEL: load i16, i16*
|
||||
; COMBINE_PTR_LABEL: store {{.*}} @__dfsan_retval_tls
|
||||
; COMBINE_PTR_LABEL: ret i16
|
||||
; CHECK-LABEL: @"dfs$load16"
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i16* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR+1]] = getelementptr i[[#SBITS]], i[[#SBITS]]* %[[#SHADOW_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = load i[[#SBITS]], i[[#SBITS]]* %[[#SHADOW_PTR]]
|
||||
; CHECK-NEXT: %[[#SHADOW+1]] = load i[[#SBITS]], i[[#SBITS]]* %[[#SHADOW_PTR+1]]
|
||||
|
||||
; NO_COMBINE_PTR_LABEL: @"dfs$load16"
|
||||
; NO_COMBINE_PTR_LABEL: ptrtoint i16*
|
||||
; NO_COMBINE_PTR_LABEL: and i64
|
||||
; NO_COMBINE_PTR_LABEL: mul i64
|
||||
; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
|
||||
; NO_COMBINE_PTR_LABEL: getelementptr i16, i16*
|
||||
; NO_COMBINE_PTR_LABEL: load i16, i16*
|
||||
; NO_COMBINE_PTR_LABEL: load i16, i16*
|
||||
; NO_COMBINE_PTR_LABEL: icmp ne i16
|
||||
; NO_COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
; NO_COMBINE_PTR_LABEL: load i16, i16*
|
||||
; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; NO_COMBINE_PTR_LABEL: ret i16
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#SHADOW+1]]
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; CHECK-NEXT: %a = load i16, i16* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#SHADOW]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i16 %a
|
||||
|
||||
%a = load i16, i16* %p
|
||||
ret i16 %a
|
||||
}
|
||||
|
||||
define i32 @load32(i32* %p) {
|
||||
; COMBINE_PTR_LABEL: @"dfs$load32"
|
||||
; COMBINE_PTR_LABEL: ptrtoint i32*
|
||||
; COMBINE_PTR_LABEL: and i64
|
||||
; COMBINE_PTR_LABEL: mul i64
|
||||
; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
|
||||
; COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
|
||||
; COMBINE_PTR_LABEL: load i64, i64*
|
||||
; COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
|
||||
; COMBINE_PTR_LABEL: shl i64
|
||||
; COMBINE_PTR_LABEL: lshr i64
|
||||
; COMBINE_PTR_LABEL: or i64
|
||||
; COMBINE_PTR_LABEL: icmp eq i64
|
||||
; COMBINE_PTR_LABEL: icmp ne i16
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
; COMBINE_PTR_LABEL: load i32, i32*
|
||||
; COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; COMBINE_PTR_LABEL: ret i32
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
|
||||
|
||||
; NO_COMBINE_PTR_LABEL: @"dfs$load32"
|
||||
; NO_COMBINE_PTR_LABEL: ptrtoint i32*
|
||||
; NO_COMBINE_PTR_LABEL: and i64
|
||||
; NO_COMBINE_PTR_LABEL: mul i64
|
||||
; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
|
||||
; NO_COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
|
||||
; NO_COMBINE_PTR_LABEL: load i64, i64*
|
||||
; NO_COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
|
||||
; NO_COMBINE_PTR_LABEL: shl i64
|
||||
; NO_COMBINE_PTR_LABEL: lshr i64
|
||||
; NO_COMBINE_PTR_LABEL: or i64
|
||||
; NO_COMBINE_PTR_LABEL: icmp eq i64
|
||||
; NO_COMBINE_PTR_LABEL: load i32, i32*
|
||||
; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; NO_COMBINE_PTR_LABEL: ret i32
|
||||
; NO_COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
|
||||
|
||||
; CHECK-LABEL: @"dfs$load32"
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i[[#WSBITS:mul(SBITS,4)]]*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = load i[[#WSBITS]], i[[#WSBITS]]* %[[#WIDE_SHADOW_PTR]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i[[#WSBITS]] %[[#WIDE_SHADOW]], [[#mul(SBITS,2)]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i[[#WSBITS]] %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i[[#WSBITS]] %[[#WIDE_SHADOW]], [[#SBITS]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i[[#WSBITS]] %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = trunc i[[#WSBITS]] %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; CHECK-NEXT: %a = load i32, i32* %p, align 4
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#SHADOW]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i32 %a
|
||||
|
||||
%a = load i32, i32* %p
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
define i64 @load64(i64* %p) {
|
||||
; COMBINE_PTR_LABEL: @"dfs$load64"
|
||||
; COMBINE_PTR_LABEL: ptrtoint i64*
|
||||
; COMBINE_PTR_LABEL: and i64
|
||||
; COMBINE_PTR_LABEL: mul i64
|
||||
; COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
|
||||
; COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
|
||||
; COMBINE_PTR_LABEL: load i64, i64*
|
||||
; COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
|
||||
; COMBINE_PTR_LABEL: shl i64
|
||||
; COMBINE_PTR_LABEL: lshr i64
|
||||
; COMBINE_PTR_LABEL: or i64
|
||||
; COMBINE_PTR_LABEL: icmp eq i64
|
||||
; COMBINE_PTR_LABEL: icmp ne i16
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
; COMBINE_PTR_LABEL: load i64, i64*
|
||||
; COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; COMBINE_PTR_LABEL: ret i64
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
|
||||
; COMBINE_PTR_LABEL: getelementptr i64, i64* {{.*}} i64
|
||||
; COMBINE_PTR_LABEL: load i64, i64*
|
||||
; COMBINE_PTR_LABEL: icmp eq i64
|
||||
|
||||
; NO_COMBINE_PTR_LABEL: @"dfs$load64"
|
||||
; NO_COMBINE_PTR_LABEL: ptrtoint i64*
|
||||
; NO_COMBINE_PTR_LABEL: and i64
|
||||
; NO_COMBINE_PTR_LABEL: mul i64
|
||||
; NO_COMBINE_PTR_LABEL: inttoptr i64 {{.*}} i16*
|
||||
; NO_COMBINE_PTR_LABEL: bitcast i16* {{.*}} i64*
|
||||
; NO_COMBINE_PTR_LABEL: load i64, i64*
|
||||
; NO_COMBINE_PTR_LABEL: trunc i64 {{.*}} i16
|
||||
; NO_COMBINE_PTR_LABEL: shl i64
|
||||
; NO_COMBINE_PTR_LABEL: lshr i64
|
||||
; NO_COMBINE_PTR_LABEL: or i64
|
||||
; NO_COMBINE_PTR_LABEL: icmp eq i64
|
||||
; NO_COMBINE_PTR_LABEL: load i64, i64*
|
||||
; NO_COMBINE_PTR_LABEL: store i16 {{.*}} @__dfsan_retval_tls
|
||||
; NO_COMBINE_PTR_LABEL: ret i64
|
||||
; NO_COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union_load
|
||||
; NO_COMBINE_PTR_LABEL: getelementptr i64, i64* {{.*}} i64
|
||||
; NO_COMBINE_PTR_LABEL: load i64, i64*
|
||||
; NO_COMBINE_PTR_LABEL: icmp eq i64
|
||||
; CHECK-LABEL: @"dfs$load64"
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i64* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i64*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = load i64, i64* %[[#WIDE_SHADOW_PTR]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; CHECK-NEXT: %a = load i64, i64* %p, align 8
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#SHADOW]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i64 %a
|
||||
|
||||
%a = load i64, i64* %p
|
||||
ret i64 %a
|
||||
}
|
||||
|
||||
define i128 @load128(i128* %p) {
|
||||
; CHECK-LABEL: @"dfs$load128"
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i128* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i64*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = load i64, i64* %[[#WIDE_SHADOW_PTR]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR2:]] = getelementptr i64, i64* %[[#WIDE_SHADOW_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW2:]] = load i64, i64* %[[#WIDE_SHADOW_PTR2]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW2]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; CHECK-NEXT: %a = load i128, i128* %p, align 8
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#SHADOW]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i128 %a
|
||||
|
||||
%a = load i128, i128* %p
|
||||
ret i128 %a
|
||||
}
|
||||
|
||||
|
||||
define i17 @load17(i17* %p) {
|
||||
; CHECK-LABEL: @"dfs$load17"
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i17* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = call zeroext i8 @__dfsan_union_load(i[[#SBITS]]* %[[#SHADOW_PTR]], i64 3)
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; CHECK-NEXT: %a = load i17, i17* %p
|
||||
; CHECK-NEXT: store i[[#SBITS]] %[[#SHADOW]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i17 %a
|
||||
|
||||
%a = load i17, i17* %p
|
||||
ret i17 %a
|
||||
}
|
||||
|
||||
@X = constant i1 1
|
||||
define i1 @load_global() {
|
||||
; NO_COMBINE_PTR_LABEL: @"dfs$load_global"
|
||||
; NO_COMBINE_PTR_LABEL: store i16 0, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align 2
|
||||
; CHECK-LABEL: @"dfs$load_global"
|
||||
; CHECK-NEXT: %a = load i1, i1* @X
|
||||
; CHECK-NEXT: store i[[#SBITS]] 0, i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK-NEXT: ret i1 %a
|
||||
|
||||
%a = load i1, i1* @X
|
||||
ret i1 %a
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s
|
||||
;
|
||||
; %15 and %17 have the same key in shadow cache. They should not reuse the same
|
||||
; shadow because their blocks do not dominate each other. Origin tracking
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels -S | FileCheck %s --check-prefixes=CHECK,CHECK8,COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,CHECK8
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels -S | FileCheck %s --check-prefixes=CHECK,CHECK16,COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,CHECK16
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -38,7 +36,6 @@ define i16* @load_escaped_alloca() {
|
|||
; CHECK-LABEL: @"dfs$load_escaped_alloca"
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i16* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR0:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_OFFSET:]] = add i64 %[[#INTP+1]], [[#%.10d,ORIGIN_MASK:]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
|
||||
|
@ -76,7 +73,6 @@ define i1 @load1(i1* %p) {
|
|||
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i1* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_OFFSET:]] = add i64 %[[#INTP+1]], [[#ORIGIN_MASK]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
|
||||
|
@ -104,7 +100,6 @@ define i16 @load16(i1 %i, i16* %p) {
|
|||
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i16* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR0:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_OFFSET:]] = add i64 %[[#INTP+1]], [[#ORIGIN_MASK]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
|
||||
|
@ -133,9 +128,8 @@ define i32 @load32(i32* %p) {
|
|||
; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i32* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = add i64 %[[#INTP+1]], [[#ORIGIN_MASK]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to i32*
|
||||
|
@ -166,41 +160,26 @@ define i64 @load64(i64* %p) {
|
|||
; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i64* %p to i64
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i64* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = add i64 %[[#INTP+1]], [[#ORIGIN_MASK]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to i32*
|
||||
; CHECK-NEXT: %[[#ORIGIN:]] = load i32, i32* %[[#ORIGIN_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i64*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = load i64, i64* %[[#WIDE_SHADOW_PTR]], align [[#SBYTES]]
|
||||
|
||||
; COMM: On fast16, the 2x64 shadow bits need to be ORed first.
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_PTR2:]] = getelementptr i64, i64* %[[#WIDE_SHADOW_PTR]], i64 1
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW2:]] = load i64, i64* %[[#WIDE_SHADOW_PTR2]], align [[#SBYTES]]
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW2]]
|
||||
; CHECK16-NEXT: %[[#ORIGIN_PTR2:]] = getelementptr i32, i32* %[[#ORIGIN_PTR]], i64 1
|
||||
; CHECK16-NEXT: %[[#ORIGIN2:]] = load i32, i32* %[[#ORIGIN_PTR2]], align 8
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK16-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2]], 0
|
||||
; CHECK16-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW_NZ]], i32 %[[#ORIGIN2]], i32 %[[#ORIGIN]]
|
||||
|
||||
; COMM: On fast8, no need to OR the wide shadow but one more shift is needed.
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_LO:]] = shl i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK8-NEXT: %[[#ORIGIN_PTR2:]] = getelementptr i32, i32* %[[#ORIGIN_PTR]], i64 1
|
||||
; CHECK8-NEXT: %[[#ORIGIN2:]] = load i32, i32* %[[#ORIGIN_PTR2]], align 8
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK8-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_LO:]] = shl i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK-NEXT: %[[#ORIGIN2_PTR:]] = getelementptr i32, i32* %[[#ORIGIN_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#ORIGIN2:]] = load i32, i32* %[[#ORIGIN2_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; CHECK-NEXT: %[[#SHADOW_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW_LO]], 0
|
||||
; CHECK-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW_NZ]], i32 %[[#ORIGIN]], i32 %[[#ORIGIN2]]
|
||||
; CHECK8-NEXT: %[[#SHADOW_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW_LO]], 0
|
||||
; CHECK8-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW_NZ]], i32 %[[#ORIGIN]], i32 %[[#ORIGIN2]]
|
||||
|
||||
|
@ -246,66 +225,38 @@ define i128 @load128(i128* %p) {
|
|||
; COMBINE_LOAD_PTR-NEXT: %[[#PO:]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#PS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i128* %p to i64
|
||||
; CHECK-NEXT: %[[#INTP:]] = ptrtoint i128* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:INTP+1]] = and i64 %[[#INTP]], [[#MASK]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = add i64 %[[#INTP+1]], [[#ORIGIN_MASK]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to i32*
|
||||
; CHECK-NEXT: %[[#ORIGIN:]] = load i32, i32* %[[#ORIGIN_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i64*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = load i64, i64* %[[#WIDE_SHADOW_PTR]], align [[#SBYTES]]
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_LO:]] = shl i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK8-NEXT: %[[#ORIGIN_PTR2:]] = getelementptr i32, i32* %[[#ORIGIN_PTR]], i64 1
|
||||
; CHECK8-NEXT: %[[#ORIGIN2:]] = load i32, i32* %[[#ORIGIN_PTR2]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_PTR2:]] = getelementptr i64, i64* %[[#WIDE_SHADOW_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW2:]] = load i64, i64* %[[#WIDE_SHADOW_PTR2]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW2]]
|
||||
|
||||
; COMM: On fast16, we need to OR 4x64bits for the wide shadow, before ORing its bytes.
|
||||
; CHECK16-NEXT: %[[#ORIGIN_PTR2:]] = getelementptr i32, i32* %[[#ORIGIN_PTR]], i64 1
|
||||
; CHECK16-NEXT: %[[#ORIGIN2:]] = load i32, i32* %[[#ORIGIN_PTR2]], align 8
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_PTR3:]] = getelementptr i64, i64* %[[#WIDE_SHADOW_PTR2]], i64 1
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW3:]] = load i64, i64* %[[#WIDE_SHADOW_PTR3]], align [[#SBYTES]]
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW3]]
|
||||
; CHECK16-NEXT: %[[#ORIGIN_PTR3:]] = getelementptr i32, i32* %[[#ORIGIN_PTR2]], i64 1
|
||||
; CHECK16-NEXT: %[[#ORIGIN3:]] = load i32, i32* %[[#ORIGIN_PTR3]], align 8
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_PTR4:]] = getelementptr i64, i64* %[[#WIDE_SHADOW_PTR3]], i64 1
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW4:]] = load i64, i64* %[[#WIDE_SHADOW_PTR4]], align [[#SBYTES]]
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW4]]
|
||||
; CHECK16-NEXT: %[[#ORIGIN_PTR4:]] = getelementptr i32, i32* %[[#ORIGIN_PTR3]], i64 1
|
||||
; CHECK16-NEXT: %[[#ORIGIN4:]] = load i32, i32* %[[#ORIGIN_PTR4]], align 8
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK16-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK16-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; CHECK16-NEXT: %[[#SHADOW2_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2]], 0
|
||||
; CHECK16-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW2_NZ]], i32 %[[#ORIGIN2]], i32 %[[#ORIGIN]]
|
||||
; CHECK16-NEXT: %[[#SHADOW3_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW3]], 0
|
||||
; CHECK16-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW3_NZ]], i32 %[[#ORIGIN3]], i32 %[[#ORIGIN]]
|
||||
; CHECK16-NEXT: %[[#SHADOW4_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW4]], 0
|
||||
; CHECK16-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW4_NZ]], i32 %[[#ORIGIN4]], i32 %[[#ORIGIN]]
|
||||
|
||||
; COMM: On fast8, we need to OR 2x64bits for the wide shadow, before ORing its bytes (one more shift).
|
||||
; CHECK8-NEXT: %[[#ORIGIN_PTR3:]] = getelementptr i32, i32* %[[#ORIGIN_PTR2]], i64 1
|
||||
; CHECK8-NEXT: %[[#ORIGIN3:]] = load i32, i32* %[[#ORIGIN_PTR3]], align 8
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW2_LO:]] = shl i64 %[[#WIDE_SHADOW2]], 32
|
||||
; CHECK8-NEXT: %[[#ORIGIN_PTR4:]] = getelementptr i32, i32* %[[#ORIGIN_PTR3]], i64 1
|
||||
; CHECK8-NEXT: %[[#ORIGIN4:]] = load i32, i32* %[[#ORIGIN_PTR4]], align 8
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
|
||||
; CHECK8-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK8-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; CHECK8-NEXT: %[[#SHADOW_LO_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW_LO]], 0
|
||||
; CHECK8-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW_LO_NZ]], i32 %[[#ORIGIN]], i32 %[[#ORIGIN2]]
|
||||
; CHECK8-NEXT: %[[#SHADOW2_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2]], 0
|
||||
; CHECK8-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW2_NZ]], i32 %[[#ORIGIN4]], i32 %[[#ORIGIN]]
|
||||
; CHECK8-NEXT: %[[#SHADOW2_LO_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2_LO]], 0
|
||||
; CHECK8-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW2_LO_NZ]], i32 %[[#ORIGIN3]], i32 %[[#ORIGIN]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = add i64 %[[#SHADOW_ADDR]], [[#ORIGIN_MASK]]
|
||||
; CHECK-NEXT: %[[#ORIGIN1_PTR:]] = inttoptr i64 %[[#ORIGIN_ADDR]] to i32*
|
||||
; CHECK-NEXT: %[[#ORIGIN1:]] = load i32, i32* %[[#ORIGIN1_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW1_PTR:]] = bitcast i[[#SBITS]]* %[[#SHADOW_PTR]] to i64*
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW1:]] = load i64, i64* %[[#WIDE_SHADOW1_PTR]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW1_LO:]] = shl i64 %[[#WIDE_SHADOW1]], 32
|
||||
; CHECK-NEXT: %[[#ORIGIN2_PTR:]] = getelementptr i32, i32* %[[#ORIGIN1_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#ORIGIN2:]] = load i32, i32* %[[#ORIGIN2_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW2_PTR:]] = getelementptr i64, i64* %[[#WIDE_SHADOW1_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW2:]] = load i64, i64* %[[#WIDE_SHADOW2_PTR]], align [[#SBYTES]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW1]], %[[#WIDE_SHADOW2]]
|
||||
; CHECK-NEXT: %[[#ORIGIN3_PTR:]] = getelementptr i32, i32* %[[#ORIGIN2_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#ORIGIN3:]] = load i32, i32* %[[#ORIGIN3_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW2_LO:]] = shl i64 %[[#WIDE_SHADOW2]], 32
|
||||
; CHECK-NEXT: %[[#ORIGIN4_PTR:]] = getelementptr i32, i32* %[[#ORIGIN3_PTR]], i64 1
|
||||
; CHECK-NEXT: %[[#ORIGIN4:]] = load i32, i32* %[[#ORIGIN4_PTR]], align 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 32
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 16
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW_SHIFTED:]] = lshr i64 %[[#WIDE_SHADOW]], 8
|
||||
; CHECK-NEXT: %[[#WIDE_SHADOW:]] = or i64 %[[#WIDE_SHADOW]], %[[#WIDE_SHADOW_SHIFTED]]
|
||||
; CHECK-NEXT: %[[#SHADOW:]] = trunc i64 %[[#WIDE_SHADOW]] to i[[#SBITS]]
|
||||
; CHECK-NEXT: %[[#SHADOW1_LO_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW1_LO]], 0
|
||||
; CHECK-NEXT: %[[#ORIGIN12:]] = select i1 %[[#SHADOW1_LO_NZ]], i32 %[[#ORIGIN1]], i32 %[[#ORIGIN2]]
|
||||
; CHECK-NEXT: %[[#SHADOW2_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2]], 0
|
||||
; CHECK-NEXT: %[[#ORIGIN124:]] = select i1 %[[#SHADOW2_NZ]], i32 %[[#ORIGIN4]], i32 %[[#ORIGIN12]]
|
||||
; CHECK-NEXT: %[[#SHADOW2_LO_NZ:]] = icmp ne i64 %[[#WIDE_SHADOW2_LO]], 0
|
||||
; CHECK-NEXT: %[[#ORIGIN:]] = select i1 %[[#SHADOW2_LO_NZ]], i32 %[[#ORIGIN3]], i32 %[[#ORIGIN124]]
|
||||
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#SHADOW:]] = or i[[#SBITS]] %[[#SHADOW]], %[[#PS]]
|
||||
; COMBINE_LOAD_PTR-NEXT: %[[#NZ:]] = icmp ne i[[#SBITS]] %[[#PS]], 0
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=1 -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,TRACK_CONTROL_FLOW
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=0 -dfsan-track-origins=1 -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CONTROL_FLOW
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=1 -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,TRACK_CONTROL_FLOW
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=0 -dfsan-track-origins=1 -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CONTROL_FLOW
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=1 -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,TRACK_CONTROL_FLOW
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=0 -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CONTROL_FLOW
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels -dfsan-combine-pointer-labels-on-store -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels -S | FileCheck %s --check-prefixes=CHECK,CHECK16
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels -dfsan-combine-pointer-labels-on-store -S | FileCheck %s --check-prefixes=CHECK,CHECK16,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-combine-pointer-labels-on-store -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -55,7 +53,6 @@ define void @store_nonzero_to_escaped_alloca(i16 %a) {
|
|||
; CHECK-NEXT: %[[#AS:]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; CHECK: %[[#INTP:]] = ptrtoint i16* %p to i64
|
||||
; CHECK-NEXT: %[[#SHADOW_ADDR:]] = and i64 %[[#INTP]], [[#%.10d,MASK:]]
|
||||
; CHECK16-NEXT: %[[#SHADOW_ADDR:]] = mul i64 %[[#SHADOW_ADDR]], 2
|
||||
; CHECK-NEXT: %[[#SHADOW_PTR0:]] = inttoptr i64 %[[#SHADOW_ADDR]] to i[[#SBITS]]*
|
||||
; CHECK-NEXT: %[[#ORIGIN_OFFSET:]] = add i64 %[[#INTP+1]], [[#%.10d,ORIGIN_MASK:]]
|
||||
; CHECK-NEXT: %[[#ORIGIN_ADDR:]] = and i64 %[[#ORIGIN_OFFSET]], -4
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-8-labels=true -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-fast-16-labels=true -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=1 -dfsan-instrument-with-call-threshold=0 -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-origins=2 -dfsan-fast-8-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=2 -dfsan-fast-16-labels -S | FileCheck %s
|
||||
; RUN: opt < %s -dfsan -dfsan-track-origins=2 -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -8,15 +6,11 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||
; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]
|
||||
|
||||
define {i32, i32} @test({i32, i32} %a, i1 %c) {
|
||||
; LEGACY: [[AL:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[PL:%.*]] = phi i[[#SBITS]] [ [[AL]], %T ], [ [[AL]], %F ]
|
||||
; LEGACY: store i[[#SBITS]] [[PL]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; FAST: [[AL:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN:2]]
|
||||
; FAST: [[AL0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[AL]], i[[#SBITS]] 0, 0
|
||||
; FAST: [[AL1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[AL]], i[[#SBITS]] 0, 1
|
||||
; FAST: [[PL:%.*]] = phi { i[[#SBITS]], i[[#SBITS]] } [ [[AL0]], %T ], [ [[AL1]], %F ]
|
||||
; FAST: store { i[[#SBITS]], i[[#SBITS]] } [[PL]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
; CHECK: %[[#AL:]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN:2]]
|
||||
; CHECK: %[[#AL0:]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } %[[#AL]], i[[#SBITS]] 0, 0
|
||||
; CHECK: %[[#AL1:]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } %[[#AL]], i[[#SBITS]] 0, 1
|
||||
; CHECK: %[[#PL:]] = phi { i[[#SBITS]], i[[#SBITS]] } [ %[[#AL0]], %T ], [ %[[#AL1]], %F ]
|
||||
; CHECK: store { i[[#SBITS]], i[[#SBITS]] } %[[#PL]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
|
||||
entry:
|
||||
br i1 %c, label %T, label %F
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=1 -S | FileCheck %s --check-prefixes=CHECK,TRACK_CF,TRACK_CF_LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=0 -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CF,NO_TRACK_CF_LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -dfsan-track-select-control-flow=1 -S | FileCheck %s --check-prefixes=CHECK,TRACK_CF,TRACK_CF_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -dfsan-track-select-control-flow=0 -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CF,NO_TRACK_CF_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -dfsan-track-select-control-flow=1 -S | FileCheck %s --check-prefixes=CHECK,TRACK_CF,TRACK_CF_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -dfsan-track-select-control-flow=0 -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CF,NO_TRACK_CF_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=true -S | FileCheck %s --check-prefixes=CHECK,TRACK_CF
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=false -S | FileCheck %s --check-prefixes=CHECK,NO_TRACK_CF
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -18,11 +14,7 @@ define i8 @select8(i1 %c, i8 %t, i8 %f) {
|
|||
; TRACK_CF: %[[#R+1]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: %[[#R+2]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: %[[#R+3]] = select i1 %c, i[[#SBITS]] %[[#R+1]], i[[#SBITS]] %[[#R]]
|
||||
; TRACK_CF_LEGACY: %[[#R+4]] = icmp ne i[[#SBITS]] %[[#R+2]], %[[#R+3]]
|
||||
; TRACK_CF_LEGACY: %[[#R+6]] = call {{.*}} i[[#SBITS]] @__dfsan_union(i[[#SBITS]] {{.*}} %[[#R+2]], i[[#SBITS]] {{.*}} %[[#R+3]])
|
||||
; TRACK_CF_LEGACY: %[[#RO:]] = phi i[[#SBITS]] [ %[[#R+6]], {{.*}} ], [ %[[#R+2]], {{.*}} ]
|
||||
; COMM: The union is simply an OR when fast labels are used.
|
||||
; TRACK_CF_FAST: %[[#RO:]] = or i[[#SBITS]] %[[#R+2]], %[[#R+3]]
|
||||
; TRACK_CF: %[[#RO:]] = or i[[#SBITS]] %[[#R+2]], %[[#R+3]]
|
||||
; TRACK_CF: %a = select i1 %c, i8 %t, i8 %f
|
||||
; TRACK_CF: store i[[#SBITS]] %[[#RO]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: ret i8 %a
|
||||
|
@ -44,11 +36,7 @@ define i8 @select8e(i1 %c, i8 %tf) {
|
|||
; TRACK_CF: @"dfs$select8e"
|
||||
; TRACK_CF: %[[#R:]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: %[[#R+1]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF_LEGACY: %[[#R+2]] = icmp ne i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; TRACK_CF_LEGACY: %[[#R+4]] = call {{.*}} i[[#SBITS]] @__dfsan_union(i[[#SBITS]] {{.*}} %[[#R+1]], i[[#SBITS]] {{.*}} %[[#R]])
|
||||
; TRACK_CF_LEGACY: %[[#RO:]] = phi i[[#SBITS]] [ %[[#R+4]], {{.*}} ], [ %[[#R+1]], {{.*}} ]
|
||||
; COMM: The union is simply an OR when fast labels are used.
|
||||
; TRACK_CF_FAST: %[[#RO:]] = or i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; TRACK_CF: %[[#RO:]] = or i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; TRACK_CF: %a = select i1 %c, i8 %tf, i8 %tf
|
||||
; TRACK_CF: store i[[#SBITS]] %[[#RO]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: ret i8 %a
|
||||
|
@ -69,15 +57,8 @@ define <4 x i8> @select8v(<4 x i1> %c, <4 x i8> %t, <4 x i8> %f) {
|
|||
; TRACK_CF: %[[#R:]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 4) to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; TRACK_CF: %[[#R+1]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: %[[#R+2]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF_LEGACY: %[[#R+3]] = icmp ne i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; TRACK_CF_LEGACY: %[[#R+5]] = call {{.*}} i[[#SBITS]] @__dfsan_union(i[[#SBITS]] {{.*}} %[[#R+1]], i[[#SBITS]] zeroext %[[#R]])
|
||||
; TRACK_CF_LEGACY: %[[#R+7]] = phi i[[#SBITS]] [ %[[#R+5]], {{.*}} ], [ %[[#R+1]], {{.*}} ]
|
||||
; TRACK_CF_LEGACY: %[[#R+8]] = icmp ne i[[#SBITS]] %[[#R+2]], %[[#R+7]]
|
||||
; TRACK_CF_LEGACY: %[[#R+10]] = call {{.*}} i[[#SBITS]] @__dfsan_union(i[[#SBITS]] {{.*}} %[[#R+2]], i[[#SBITS]] zeroext %[[#R+7]])
|
||||
; TRACK_CF_LEGACY: %[[#RO:]] = phi i[[#SBITS]] [ %[[#R+10]], {{.*}} ], [ %[[#R+2]], {{.*}} ]
|
||||
; COMM: The union is simply an OR when fast labels are used.
|
||||
; TRACK_CF_FAST: %[[#R+3]] = or i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; TRACK_CF_FAST: %[[#RO:]] = or i[[#SBITS]] %[[#R+2]], %[[#R+3]]
|
||||
; TRACK_CF: %[[#R+3]] = or i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; TRACK_CF: %[[#RO:]] = or i[[#SBITS]] %[[#R+2]], %[[#R+3]]
|
||||
; TRACK_CF: %a = select <4 x i1> %c, <4 x i8> %t, <4 x i8> %f
|
||||
; TRACK_CF: store i[[#SBITS]] %[[#RO]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; TRACK_CF: ret <4 x i8> %a
|
||||
|
@ -86,11 +67,7 @@ define <4 x i8> @select8v(<4 x i1> %c, <4 x i8> %t, <4 x i8> %f) {
|
|||
; NO_TRACK_CF: %[[#R:]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 4) to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; NO_TRACK_CF: %[[#R+1]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; NO_TRACK_CF: %[[#R+2]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; NO_TRACK_CF_LEGACY: %[[#R+3]] = icmp ne i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; NO_TRACK_CF_LEGACY: %[[#R+5]] = call {{.*}} i[[#SBITS]] @__dfsan_union(i[[#SBITS]] {{.*}} %[[#R+1]], i[[#SBITS]] {{.*}} %[[#R]])
|
||||
; NO_TRACK_CF_LEGACY: %[[#RO:]] = phi i[[#SBITS]] [ %6, {{.*}} ], [ %2, {{.*}} ]
|
||||
; COMM: The union is simply an OR when fast labels are used.
|
||||
; NO_TRACK_CF_FAST: %[[#RO:]] = or i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; NO_TRACK_CF: %[[#RO:]] = or i[[#SBITS]] %[[#R+1]], %[[#R]]
|
||||
; NO_TRACK_CF: %a = select <4 x i1> %c, <4 x i8> %t, <4 x i8> %f
|
||||
; NO_TRACK_CF: store i[[#SBITS]] %[[#RO]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; NO_TRACK_CF: ret <4 x i8> %a
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt | FileCheck %s
|
||||
; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt -dfsan-fast-16-labels | FileCheck %s
|
||||
; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt -dfsan-fast-8-labels | FileCheck %s
|
||||
|
||||
; REQUIRES: x86-registered-target
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK16,COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK16,NO_COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -dfsan-combine-pointer-labels-on-store=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK16,COMBINE_PTR_LABEL_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels -dfsan-combine-pointer-labels-on-store=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK16,NO_COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -dfsan-combine-pointer-labels-on-store=1 -S | FileCheck %s --check-prefixes=CHECK,COMBINE_PTR_LABEL_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels -dfsan-combine-pointer-labels-on-store=0 -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=1 -S | FileCheck %s --check-prefixes=CHECK,COMBINE_PTR_LABEL
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=0 -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_PTR_LABEL
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -23,19 +19,10 @@ define void @store0({} %v, {}* %p) {
|
|||
define void @store8(i8 %v, i8* %p) {
|
||||
; CHECK-LABEL: @"dfs$store8"
|
||||
; CHECK: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
|
||||
; COMBINE_PTR_LABEL: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL: icmp ne i[[#SBITS]]
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
|
||||
; COMM: When not in legacy mode, the three instructions above will
|
||||
; be replaced with the following:
|
||||
; COMBINE_PTR_LABEL_FAST: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL_FAST: or i[[#SBITS]]
|
||||
|
||||
; COMBINE_PTR_LABEL: or i[[#SBITS]]
|
||||
; CHECK: ptrtoint i8* {{.*}} i64
|
||||
; CHECK-NEXT: and i64
|
||||
; CHECK16-NEXT: mul i64
|
||||
; CHECK-NEXT: inttoptr i64 {{.*}} i[[#SBITS]]*
|
||||
; CHECK-NEXT: getelementptr i[[#SBITS]], i[[#SBITS]]*
|
||||
; CHECK-NEXT: store i[[#SBITS]]
|
||||
|
@ -49,19 +36,10 @@ define void @store8(i8 %v, i8* %p) {
|
|||
define void @store16(i16 %v, i16* %p) {
|
||||
; CHECK-LABEL: @"dfs$store16"
|
||||
; CHECK: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
|
||||
; COMBINE_PTR_LABEL: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL: icmp ne i[[#SBITS]]
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
|
||||
; COMM: When not in legacy mode, the three instructions above will
|
||||
; be replaced with the following:
|
||||
; COMBINE_PTR_LABEL_FAST: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL_FAST: or i[[#SBITS]]
|
||||
|
||||
; COMBINE_PTR_LABEL: or i[[#SBITS]]
|
||||
; CHECK: ptrtoint i16* {{.*}} i64
|
||||
; CHECK-NEXT: and i64
|
||||
; CHECK16-NEXT: mul i64
|
||||
; CHECK-NEXT: inttoptr i64 {{.*}} i[[#SBITS]]*
|
||||
; CHECK-NEXT: getelementptr i[[#SBITS]], i[[#SBITS]]*
|
||||
; CHECK-NEXT: store i[[#SBITS]]
|
||||
|
@ -77,19 +55,10 @@ define void @store16(i16 %v, i16* %p) {
|
|||
define void @store32(i32 %v, i32* %p) {
|
||||
; CHECK-LABEL: @"dfs$store32"
|
||||
; CHECK: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
|
||||
; COMBINE_PTR_LABEL: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL: icmp ne i[[#SBITS]]
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
|
||||
; COMM: When not in legacy mode, the three instructions above will
|
||||
; be replaced with the following:
|
||||
; COMBINE_PTR_LABEL_FAST: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL_FAST: or i[[#SBITS]]
|
||||
|
||||
; COMBINE_PTR_LABEL: or i[[#SBITS]]
|
||||
; CHECK: ptrtoint i32* {{.*}} i64
|
||||
; CHECK-NEXT: and i64
|
||||
; CHECK16-NEXT: mul i64
|
||||
; CHECK-NEXT: inttoptr i64 {{.*}} i[[#SBITS]]*
|
||||
; CHECK-NEXT: getelementptr i[[#SBITS]], i[[#SBITS]]*
|
||||
; CHECK-NEXT: store i[[#SBITS]]
|
||||
|
@ -109,19 +78,10 @@ define void @store32(i32 %v, i32* %p) {
|
|||
define void @store64(i64 %v, i64* %p) {
|
||||
; CHECK-LABEL: @"dfs$store64"
|
||||
; CHECK: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
|
||||
; COMBINE_PTR_LABEL: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL: icmp ne i[[#SBITS]]
|
||||
; COMBINE_PTR_LABEL: call {{.*}} @__dfsan_union
|
||||
|
||||
; COMM: When not in legacy mode, the three instructions above will
|
||||
; be replaced with the following:
|
||||
; COMBINE_PTR_LABEL_FAST: load i[[#SBITS]], i[[#SBITS]]* {{.*}} @__dfsan_arg_tls
|
||||
; COMBINE_PTR_LABEL_FAST: or i[[#SBITS]]
|
||||
|
||||
; COMBINE_PTR_LABEL: or i[[#SBITS]]
|
||||
; CHECK: ptrtoint i64* {{.*}} i64
|
||||
; CHECK-NEXT: and i64
|
||||
; CHECK16-NEXT: mul i64
|
||||
; CHECK-NEXT: inttoptr i64 {{.*}} i[[#SBITS]]*
|
||||
; CHECK-COUNT-8: insertelement {{.*}} i[[#SBITS]]
|
||||
; CHECK-NEXT: bitcast i[[#SBITS]]* {{.*}} <8 x i[[#SBITS]]>*
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS
|
||||
; RUN: opt < %s -dfsan -dfsan-event-callbacks=true -S | FileCheck %s --check-prefixes=CHECK,EVENT_CALLBACKS
|
||||
; RUN: opt < %s -dfsan -dfsan-args-abi -S | FileCheck %s --check-prefixes=CHECK,ARGS_ABI
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-track-select-control-flow=false -S | FileCheck %s --check-prefixes=CHECK,NO_SELECT_CONTROL
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-track-select-control-flow=false -S | FileCheck %s --check-prefixes=CHECK,NO_SELECT_CONTROL
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-load=false -S | FileCheck %s --check-prefixes=CHECK,NO_COMBINE_LOAD_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-combine-pointer-labels-on-store=true -S | FileCheck %s --check-prefixes=CHECK,COMBINE_STORE_PTR
|
||||
; RUN: opt < %s -dfsan -dfsan-track-select-control-flow=false -S | FileCheck %s --check-prefixes=CHECK,NO_SELECT_CONTROL
|
||||
; RUN: opt < %s -dfsan -dfsan-debug-nonzero-labels -S | FileCheck %s --check-prefixes=CHECK,DEBUG_NONZERO_LABELS
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -91,11 +85,6 @@ define {i1, i32} @select_struct(i1 %c, {i1, i32} %a, {i1, i32} %b) {
|
|||
; FAST: %[[#R+9]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } %[[#R+8]], i[[#SBITS]] %[[#R+7]], 1
|
||||
; FAST: store { i[[#SBITS]], i[[#SBITS]] } %[[#R+9]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
|
||||
; LEGACY: @"dfs$select_struct"
|
||||
; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union
|
||||
; LEGACY: [[P:%.*]] = phi i[[#SBITS]] [ [[U]],
|
||||
; LEGACY: store i[[#SBITS]] [[P]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2
|
||||
|
||||
%s = select i1 %c, {i1, i32} %a, {i1, i32} %b
|
||||
ret {i1, i32} %s
|
||||
}
|
||||
|
@ -109,13 +98,6 @@ define { i32, i32 } @asm_struct(i32 %0, i32 %1) {
|
|||
; FAST: [[S1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[S0]], i[[#SBITS]] [[E01]], 1
|
||||
; FAST: store { i[[#SBITS]], i[[#SBITS]] } [[S1]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
|
||||
; LEGACY: @"dfs$asm_struct"
|
||||
; LEGACY: [[E1:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[E0:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; LEGACY: [[E01:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[E0]], i[[#SBITS]] zeroext [[E1]])
|
||||
; LEGACY: [[P:%.*]] = phi i[[#SBITS]] [ [[E01]], {{.*}} ], [ [[E0]], {{.*}} ]
|
||||
; LEGACY: store i[[#SBITS]] [[P]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
entry:
|
||||
%a = call { i32, i32 } asm "", "=r,=r,r,r,~{dirflag},~{fpsr},~{flags}"(i32 %0, i32 %1)
|
||||
ret { i32, i32 } %a
|
||||
|
@ -124,9 +106,6 @@ entry:
|
|||
define {i32, i32} @const_struct() {
|
||||
; FAST: @"dfs$const_struct"
|
||||
; FAST: store { i[[#SBITS]], i[[#SBITS]] } zeroinitializer, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align 2
|
||||
|
||||
; LEGACY: @"dfs$const_struct"
|
||||
; LEGACY: store i[[#SBITS]] 0, i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2
|
||||
ret {i32, i32} { i32 42, i32 11 }
|
||||
}
|
||||
|
||||
|
@ -136,9 +115,6 @@ define i1 @extract_struct({i1, i5} %s) {
|
|||
; FAST: [[EM:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[SM]], 0
|
||||
; FAST: store i[[#SBITS]] [[EM]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; LEGACY: @"dfs$extract_struct"
|
||||
; LEGACY: [[SM:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: store i[[#SBITS]] [[SM]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
%e2 = extractvalue {i1, i5} %s, 0
|
||||
ret i1 %e2
|
||||
}
|
||||
|
@ -149,13 +125,6 @@ define {i1, i5} @insert_struct({i1, i5} %s, i5 %e1) {
|
|||
; FAST: [[SM:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
; FAST: [[SM1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[SM]], i[[#SBITS]] [[EM]], 1
|
||||
; FAST: store { i[[#SBITS]], i[[#SBITS]] } [[SM1]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]]
|
||||
|
||||
; LEGACY: @"dfs$insert_struct"
|
||||
; LEGACY: [[EM:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([[TLS_ARR]]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; LEGACY: [[SM:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
; LEGACY: [[U:%.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext [[SM]], i[[#SBITS]] zeroext [[EM]])
|
||||
; LEGACY: [[P:%.*]] = phi i[[#SBITS]] [ [[U]], {{.*}} ], [ [[SM]], {{.*}} ]
|
||||
; LEGACY: store i[[#SBITS]] [[P]], i[[#SBITS]]* bitcast ([[TLS_ARR]]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
%s1 = insertvalue {i1, i5} %s, i5 %e1, 1
|
||||
ret {i1, i5} %s1
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,9 @@
|
|||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]]
|
||||
; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]
|
||||
|
||||
@a = common global i32 0
|
||||
@b = common global i32 0
|
||||
|
||||
|
@ -9,10 +12,10 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||
|
||||
; CHECK-LABEL: @"dfs$f"
|
||||
define void @f(i32 %x, i32 %y) {
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: or i[[#SBITS]]
|
||||
%xay = add i32 %x, %y
|
||||
store i32 %xay, i32* @a
|
||||
; CHECK-NOT: call{{.*}}__dfsan_union
|
||||
; CHECK-NOT: or i[[#SBITS]]
|
||||
%xmy = mul i32 %x, %y
|
||||
store i32 %xmy, i32* @b
|
||||
ret void
|
||||
|
@ -26,13 +29,13 @@ define void @g(i1 %p, i32 %x, i32 %y) {
|
|||
br i1 %p, label %l1, label %l2
|
||||
|
||||
l1:
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: or i[[#SBITS]]
|
||||
%xay = add i32 %x, %y
|
||||
store i32 %xay, i32* @a
|
||||
br label %l3
|
||||
|
||||
l2:
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: or i[[#SBITS]]
|
||||
%xmy = mul i32 %x, %y
|
||||
store i32 %xmy, i32* @b
|
||||
br label %l3
|
||||
|
@ -45,9 +48,9 @@ l3:
|
|||
|
||||
; CHECK-LABEL: @"dfs$h"
|
||||
define i32 @h(i32 %x, i32 %y) {
|
||||
; CHECK: call{{.*}}__dfsan_union
|
||||
; CHECK: or i[[#SBITS]]
|
||||
%xay = add i32 %x, %y
|
||||
; CHECK-NOT: call{{.*}}__dfsan_union
|
||||
; CHECK-NOT: or i[[#SBITS]]
|
||||
%xayax = add i32 %xay, %x
|
||||
ret i32 %xayax
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI,TLS_ABI_LEGACY
|
||||
; RUN: opt < %s -dfsan -dfsan-args-abi -S | FileCheck %s --check-prefixes=CHECK,ARGS_ABI
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-16-labels=true -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI,TLS_ABI_FAST
|
||||
; RUN: opt < %s -dfsan -dfsan-fast-8-labels=true -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI,TLS_ABI_FAST
|
||||
; RUN: opt < %s -dfsan -S | FileCheck %s --check-prefixes=CHECK,TLS_ABI
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -37,12 +35,7 @@ define <4 x i1> @icmp_vector(<4 x i8> %a, <4 x i8> %b) {
|
|||
; TLS_ABI-LABEL: @"dfs$icmp_vector"
|
||||
; TLS_ABI-NEXT: %[[B:.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align [[ALIGN:2]]
|
||||
; TLS_ABI-NEXT: %[[A:.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
||||
; TLS_ABI_LEGACY: %[[U:.*]] = call zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext %[[A]], i[[#SBITS]] zeroext %[[B]])
|
||||
; TLS_ABI_LEGACY: %[[L:.*]] = phi i[[#SBITS]] [ %[[U]], {{.*}} ], [ %[[A]], {{.*}} ]
|
||||
|
||||
; COM: With fast labels enabled, union is just an OR.
|
||||
; TLS_ABI_FAST: %[[L:.*]] = or i[[#SBITS]] %[[A]], %[[B]]
|
||||
; TLS_ABI: %[[L:.*]] = or i[[#SBITS]] %[[A]], %[[B]]
|
||||
|
||||
; TLS_ABI: %r = icmp eq <4 x i8> %a, %b
|
||||
; TLS_ABI: store i[[#SBITS]] %[[L]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align [[ALIGN]]
|
||||
|
|
Loading…
Reference in New Issue