152f889abSMatt Morehouse // RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
252f889abSMatt Morehouse // RUN: %clang_dfsan -O2 -mllvm -dfsan-event-callbacks %s %t-callbacks.o -o %t
3f668baa4SMatt Morehouse // RUN: %run %t FooBarBaz 2>&1 | FileCheck %s
4470db54cSMatt Morehouse
5470db54cSMatt Morehouse // Tests that callbacks are inserted for store events when
6470db54cSMatt Morehouse // -dfsan-event-callbacks is specified.
7470db54cSMatt Morehouse
8470db54cSMatt Morehouse #include <assert.h>
9470db54cSMatt Morehouse #include <sanitizer/dfsan_interface.h>
10470db54cSMatt Morehouse #include <stdio.h>
11f668baa4SMatt Morehouse #include <string.h>
12470db54cSMatt Morehouse
13470db54cSMatt Morehouse #ifdef CALLBACKS
14470db54cSMatt Morehouse // Compile this code without DFSan to avoid recursive instrumentation.
15470db54cSMatt Morehouse
16470db54cSMatt Morehouse extern dfsan_label LabelI;
17470db54cSMatt Morehouse extern dfsan_label LabelJ;
18470db54cSMatt Morehouse extern dfsan_label LabelIJ;
19f668baa4SMatt Morehouse extern dfsan_label LabelArgv;
20f668baa4SMatt Morehouse extern size_t LenArgv;
21470db54cSMatt Morehouse
__dfsan_store_callback(dfsan_label Label)22470db54cSMatt Morehouse void __dfsan_store_callback(dfsan_label Label) {
23470db54cSMatt Morehouse if (!Label)
24470db54cSMatt Morehouse return;
25470db54cSMatt Morehouse
26470db54cSMatt Morehouse static int Count = 0;
27470db54cSMatt Morehouse switch (Count++) {
28470db54cSMatt Morehouse case 0:
29470db54cSMatt Morehouse assert(Label == LabelI);
30470db54cSMatt Morehouse break;
31470db54cSMatt Morehouse case 1:
32470db54cSMatt Morehouse assert(Label == LabelJ);
33470db54cSMatt Morehouse break;
34470db54cSMatt Morehouse case 2:
35470db54cSMatt Morehouse assert(Label == LabelIJ);
36470db54cSMatt Morehouse break;
37470db54cSMatt Morehouse default:
38470db54cSMatt Morehouse assert(0);
39470db54cSMatt Morehouse }
40470db54cSMatt Morehouse
41470db54cSMatt Morehouse fprintf(stderr, "Label %u stored to memory\n", Label);
42470db54cSMatt Morehouse }
43470db54cSMatt Morehouse
__dfsan_load_callback(dfsan_label Label)4452f889abSMatt Morehouse void __dfsan_load_callback(dfsan_label Label) {
4552f889abSMatt Morehouse if (!Label)
4652f889abSMatt Morehouse return;
4752f889abSMatt Morehouse
4852f889abSMatt Morehouse fprintf(stderr, "Label %u loaded from memory\n", Label);
4952f889abSMatt Morehouse }
5052f889abSMatt Morehouse
__dfsan_mem_transfer_callback(dfsan_label * Start,size_t Len)51f668baa4SMatt Morehouse void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len) {
52f668baa4SMatt Morehouse assert(Len == LenArgv);
53f668baa4SMatt Morehouse for (int I = 0; I < Len; ++I) {
54f668baa4SMatt Morehouse assert(Start[I] == LabelArgv);
55f668baa4SMatt Morehouse }
56f668baa4SMatt Morehouse
57f668baa4SMatt Morehouse fprintf(stderr, "Label %u copied to memory\n", Start[0]);
58f668baa4SMatt Morehouse }
59f668baa4SMatt Morehouse
__dfsan_cmp_callback(dfsan_label CombinedLabel)6030bb737aSMatt Morehouse void __dfsan_cmp_callback(dfsan_label CombinedLabel) {
6130bb737aSMatt Morehouse if (!CombinedLabel)
6230bb737aSMatt Morehouse return;
6330bb737aSMatt Morehouse
6430bb737aSMatt Morehouse fprintf(stderr, "Label %u used for branching\n", CombinedLabel);
6530bb737aSMatt Morehouse }
6630bb737aSMatt Morehouse
67470db54cSMatt Morehouse #else
68470db54cSMatt Morehouse // Compile this code with DFSan and -dfsan-event-callbacks to insert the
69470db54cSMatt Morehouse // callbacks.
70470db54cSMatt Morehouse
71470db54cSMatt Morehouse dfsan_label LabelI;
72470db54cSMatt Morehouse dfsan_label LabelJ;
73470db54cSMatt Morehouse dfsan_label LabelIJ;
74f668baa4SMatt Morehouse dfsan_label LabelArgv;
75470db54cSMatt Morehouse
76f668baa4SMatt Morehouse size_t LenArgv;
77f668baa4SMatt Morehouse
main(int Argc,char * Argv[])78f668baa4SMatt Morehouse int main(int Argc, char *Argv[]) {
79f668baa4SMatt Morehouse assert(Argc == 2);
80f668baa4SMatt Morehouse
81470db54cSMatt Morehouse int I = 1, J = 2;
82*5b4dda55SGeorge Balatsouras LabelI = 1;
83470db54cSMatt Morehouse dfsan_set_label(LabelI, &I, sizeof(I));
84*5b4dda55SGeorge Balatsouras LabelJ = 2;
85470db54cSMatt Morehouse dfsan_set_label(LabelJ, &J, sizeof(J));
86470db54cSMatt Morehouse LabelIJ = dfsan_union(LabelI, LabelJ);
87470db54cSMatt Morehouse
8852f889abSMatt Morehouse // CHECK: Label 1 stored to memory
89470db54cSMatt Morehouse volatile int Sink = I;
9052f889abSMatt Morehouse
9152f889abSMatt Morehouse // CHECK: Label 1 loaded from memory
9230bb737aSMatt Morehouse // CHECK: Label 1 used for branching
9352f889abSMatt Morehouse assert(Sink == 1);
9452f889abSMatt Morehouse
9552f889abSMatt Morehouse // CHECK: Label 2 stored to memory
96470db54cSMatt Morehouse Sink = J;
9752f889abSMatt Morehouse
9852f889abSMatt Morehouse // CHECK: Label 2 loaded from memory
9930bb737aSMatt Morehouse // CHECK: Label 2 used for branching
10052f889abSMatt Morehouse assert(Sink == 2);
10152f889abSMatt Morehouse
10252f889abSMatt Morehouse // CHECK: Label 2 loaded from memory
10352f889abSMatt Morehouse // CHECK: Label 3 stored to memory
104470db54cSMatt Morehouse Sink += I;
105470db54cSMatt Morehouse
10652f889abSMatt Morehouse // CHECK: Label 3 loaded from memory
10730bb737aSMatt Morehouse // CHECK: Label 3 used for branching
10852f889abSMatt Morehouse assert(Sink == 3);
10952f889abSMatt Morehouse
11030bb737aSMatt Morehouse // CHECK: Label 3 used for branching
11130bb737aSMatt Morehouse assert(I != J);
11230bb737aSMatt Morehouse
113f668baa4SMatt Morehouse LenArgv = strlen(Argv[1]);
114*5b4dda55SGeorge Balatsouras LabelArgv = 4;
115f668baa4SMatt Morehouse dfsan_set_label(LabelArgv, Argv[1], LenArgv);
116f668baa4SMatt Morehouse
1172df6efedSMatt Morehouse char Buf[64];
1182df6efedSMatt Morehouse assert(LenArgv < sizeof(Buf) - 1);
119f668baa4SMatt Morehouse
120f668baa4SMatt Morehouse // CHECK: Label 4 copied to memory
1212df6efedSMatt Morehouse void *volatile SinkPtr = Buf;
1222df6efedSMatt Morehouse memcpy(SinkPtr, Argv[1], LenArgv);
123f668baa4SMatt Morehouse
124f668baa4SMatt Morehouse // CHECK: Label 4 copied to memory
1252df6efedSMatt Morehouse SinkPtr = &Buf[1];
1262df6efedSMatt Morehouse memmove(SinkPtr, Buf, LenArgv);
127f668baa4SMatt Morehouse
128470db54cSMatt Morehouse return 0;
129470db54cSMatt Morehouse }
130470db54cSMatt Morehouse
131470db54cSMatt Morehouse #endif // #ifdef CALLBACKS
132