Skip to content

Commit 7f0f912

Browse files
committed
only write if file exists
1 parent 1e66840 commit 7f0f912

File tree

4 files changed

+114
-129
lines changed

4 files changed

+114
-129
lines changed

llvm/lib/Transforms/Utils/CFFunctionInstrumentation.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
3232
// name of the function
3333
for (auto &BB : F) {
3434
// Do NOT reinstrument the inserted blocks
35-
if (BB.getName() == "return" || BB.getName() == "print" || BB.getName() == "open") {
35+
if (BB.getName() == "return" || BB.getName() == "print" ||
36+
BB.getName() == "open") {
3637
continue;
3738
}
3839
if (auto *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
@@ -53,6 +54,7 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
5354
false));
5455
Value *FileName = OrigBuilder.CreateGlobalStringPtr(funcFileName);
5556
Value *WritePermission = OrigBuilder.CreateGlobalStringPtr("a");
57+
Value *ReadPermission = OrigBuilder.CreateGlobalStringPtr("r");
5658

5759
// split at return
5860
BasicBlock *ReturnBB = BB.splitBasicBlock(RI, "return", false);
@@ -61,11 +63,11 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
6163
BasicBlock *PrintBB = BasicBlock::Create(M.getContext(), "print", &F);
6264

6365
IRBuilder<> OpenBuilder(OpenBB);
64-
Value *fptr =
65-
OpenBuilder.CreateCall(OpenFunc, {FileName, WritePermission});
66+
Value *read_fptr =
67+
OpenBuilder.CreateCall(OpenFunc, {FileName, ReadPermission});
6668

6769
Value *Cmp = OpenBuilder.CreateICmpNE(
68-
fptr,
70+
read_fptr,
6971
ConstantPointerNull::get(PointerType::get(M.getContext(), 0)));
7072
OpenBuilder.CreateCondBr(Cmp, PrintBB, ReturnBB);
7173

@@ -77,15 +79,20 @@ CFFunctionInstrumentationPass::run(Module &M, ModuleAnalysisManager &AM) {
7779
Value *formatStrPtr =
7880
PrintBuilder.CreateGlobalStringPtr(funcFormatStr);
7981
// if the file pointer is null, return
80-
81-
PrintBuilder.CreateCall(PrintFunc, {fptr, formatStrPtr, retVal});
82-
83-
// insert call to fclose
8482
FunctionCallee CloseFunc = M.getOrInsertFunction(
8583
"fclose",
8684
FunctionType::get(Type::getInt32Ty(M.getContext()),
8785
{PointerType::get(M.getContext(), 0)}, false));
88-
PrintBuilder.CreateCall(CloseFunc, fptr);
86+
PrintBuilder.CreateCall(CloseFunc, read_fptr);
87+
88+
Value *write_fptr =
89+
PrintBuilder.CreateCall(OpenFunc, {FileName, WritePermission});
90+
PrintBuilder.CreateCall(PrintFunc,
91+
{write_fptr, formatStrPtr, retVal});
92+
93+
// insert call to fclose
94+
95+
PrintBuilder.CreateCall(CloseFunc, write_fptr);
8996
PrintBuilder.CreateBr(ReturnBB);
9097

9198
BB.getTerminator()->setSuccessor(0, OpenBB);

print_example/function_trace.txt

Lines changed: 0 additions & 9 deletions
This file was deleted.

print_example/instrumented

0 Bytes
Binary file not shown.

print_example/instrumented.ll

Lines changed: 98 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,141 @@
11
; ModuleID = 'test.ll'
22
source_filename = "test.ll"
33

4-
@0 = private unnamed_addr constant [24 x i8] c"foo return value: %lld\0A\00", align 1
5-
@1 = private unnamed_addr constant [24 x i8] c"bat return value: %lld\0A\00", align 1
6-
@2 = private unnamed_addr constant [19 x i8] c"function_trace.txt\00", align 1
7-
@3 = private unnamed_addr constant [2 x i8] c"a\00", align 1
8-
@4 = private unnamed_addr constant [24 x i8] c"baz return value: %lld\0A\00", align 1
9-
10-
define noundef i1 @foo() local_unnamed_addr {
11-
open:
12-
%0 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
13-
%.not = icmp eq ptr %0, null
14-
br i1 %.not, label %return, label %print
4+
@0 = private unnamed_addr constant [19 x i8] c"function_trace.txt\00", align 1
5+
@1 = private unnamed_addr constant [2 x i8] c"a\00", align 1
6+
@2 = private unnamed_addr constant [2 x i8] c"r\00", align 1
7+
@3 = private unnamed_addr constant [24 x i8] c"foo return value: %lld\0A\00", align 1
8+
@4 = private unnamed_addr constant [19 x i8] c"function_trace.txt\00", align 1
9+
@5 = private unnamed_addr constant [2 x i8] c"a\00", align 1
10+
@6 = private unnamed_addr constant [2 x i8] c"r\00", align 1
11+
@7 = private unnamed_addr constant [24 x i8] c"bat return value: %lld\0A\00", align 1
12+
@8 = private unnamed_addr constant [19 x i8] c"function_trace.txt\00", align 1
13+
@9 = private unnamed_addr constant [2 x i8] c"a\00", align 1
14+
@10 = private unnamed_addr constant [2 x i8] c"r\00", align 1
15+
@11 = private unnamed_addr constant [24 x i8] c"baz return value: %lld\0A\00", align 1
16+
17+
define i1 @foo() {
18+
br label %open
19+
20+
open: ; preds = %0
21+
%1 = call ptr @fopen(ptr @0, ptr @2)
22+
%2 = icmp ne ptr %1, null
23+
br i1 %2, label %print, label %return
1524

1625
print: ; preds = %open
17-
tail call void (ptr, ...) @fprintf(ptr nonnull %0, ptr nonnull @0, i1 false)
18-
%1 = tail call i32 @fclose(ptr nonnull %0)
26+
%3 = call i32 @fclose(ptr %1)
27+
%4 = call ptr @fopen(ptr @0, ptr @1)
28+
call void (ptr, ...) @fprintf(ptr %4, ptr @3, i1 false)
29+
%5 = call i32 @fclose(ptr %4)
1930
br label %return
2031

2132
return: ; preds = %print, %open
2233
ret i1 false
2334
}
2435

25-
define noundef i32 @bat() local_unnamed_addr {
26-
open:
27-
%0 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
28-
%.not = icmp eq ptr %0, null
29-
br i1 %.not, label %return, label %print
36+
define i32 @bat() {
37+
br label %open
38+
39+
open: ; preds = %0
40+
%1 = call ptr @fopen(ptr @4, ptr @6)
41+
%2 = icmp ne ptr %1, null
42+
br i1 %2, label %print, label %return
3043

3144
print: ; preds = %open
32-
tail call void (ptr, ...) @fprintf(ptr nonnull %0, ptr nonnull @1, i32 0)
33-
%1 = tail call i32 @fclose(ptr nonnull %0)
45+
%3 = call i32 @fclose(ptr %1)
46+
%4 = call ptr @fopen(ptr @4, ptr @5)
47+
call void (ptr, ...) @fprintf(ptr %4, ptr @7, i32 0)
48+
%5 = call i32 @fclose(ptr %4)
3449
br label %return
3550

3651
return: ; preds = %print, %open
3752
ret i32 0
3853
}
3954

40-
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
41-
define void @bar() local_unnamed_addr #0 {
55+
define void @bar() {
4256
ret void
4357
}
4458

45-
define noundef i32 @baz() local_unnamed_addr {
46-
end:
47-
%0 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
48-
%.not.i = icmp eq ptr %0, null
49-
br i1 %.not.i, label %foo.exit, label %print.i
50-
51-
print.i: ; preds = %end
52-
tail call void (ptr, ...) @fprintf(ptr nonnull %0, ptr nonnull @0, i1 false)
53-
%1 = tail call i32 @fclose(ptr nonnull %0)
54-
br label %foo.exit
55-
56-
foo.exit: ; preds = %end, %print.i
57-
%2 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
58-
%.not = icmp eq ptr %2, null
59-
br i1 %.not, label %return, label %print
60-
61-
print: ; preds = %foo.exit
62-
tail call void (ptr, ...) @fprintf(ptr nonnull %2, ptr nonnull @4, i32 5)
63-
%3 = tail call i32 @fclose(ptr nonnull %2)
59+
define i32 @baz() {
60+
%1 = call i1 @foo()
61+
br i1 %1, label %then, label %else
62+
63+
then: ; preds = %0
64+
br label %end
65+
66+
else: ; preds = %0
67+
br label %end
68+
69+
end: ; preds = %else, %then
70+
br label %open
71+
72+
open: ; preds = %end
73+
%2 = call ptr @fopen(ptr @8, ptr @10)
74+
%3 = icmp ne ptr %2, null
75+
br i1 %3, label %print, label %return
76+
77+
print: ; preds = %open
78+
%4 = call i32 @fclose(ptr %2)
79+
%5 = call ptr @fopen(ptr @8, ptr @9)
80+
call void (ptr, ...) @fprintf(ptr %5, ptr @11, i32 5)
81+
%6 = call i32 @fclose(ptr %5)
6482
br label %return
6583

66-
return: ; preds = %print, %foo.exit
84+
return: ; preds = %print, %open
6785
ret i32 5
6886
}
6987

70-
define noundef i32 @qux() local_unnamed_addr {
71-
end:
72-
%0 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
73-
%.not.i = icmp eq ptr %0, null
74-
br i1 %.not.i, label %bat.exit, label %print.i
88+
define i32 @qux() {
89+
%1 = call i32 @bat()
90+
%2 = icmp eq i32 %1, 0
91+
br i1 %2, label %then, label %else
92+
93+
then: ; preds = %0
94+
br label %end
7595

76-
print.i: ; preds = %end
77-
tail call void (ptr, ...) @fprintf(ptr nonnull %0, ptr nonnull @1, i32 0)
78-
%1 = tail call i32 @fclose(ptr nonnull %0)
79-
br label %bat.exit
96+
else: ; preds = %0
97+
br label %end
8098

81-
bat.exit: ; preds = %end, %print.i
99+
end: ; preds = %else, %then
82100
ret i32 5
83101
}
84102

85-
define noundef i32 @quuz() local_unnamed_addr {
86-
end:
87-
%0 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
88-
%.not.i.i = icmp eq ptr %0, null
89-
br i1 %.not.i.i, label %foo.exit.i, label %print.i.i
90-
91-
print.i.i: ; preds = %end
92-
tail call void (ptr, ...) @fprintf(ptr nonnull %0, ptr nonnull @0, i1 false)
93-
%1 = tail call i32 @fclose(ptr nonnull %0)
94-
br label %foo.exit.i
95-
96-
foo.exit.i: ; preds = %print.i.i, %end
97-
%2 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
98-
%.not.i = icmp eq ptr %2, null
99-
br i1 %.not.i, label %baz.exit, label %print.i
100-
101-
print.i: ; preds = %foo.exit.i
102-
tail call void (ptr, ...) @fprintf(ptr nonnull %2, ptr nonnull @4, i32 5)
103-
%3 = tail call i32 @fclose(ptr nonnull %2)
104-
br label %baz.exit
105-
106-
baz.exit: ; preds = %foo.exit.i, %print.i
107-
%4 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
108-
%.not.i1 = icmp eq ptr %4, null
109-
br i1 %.not.i1, label %bat.exit, label %print.i2
110-
111-
print.i2: ; preds = %baz.exit
112-
tail call void (ptr, ...) @fprintf(ptr nonnull %4, ptr nonnull @1, i32 0)
113-
%5 = tail call i32 @fclose(ptr nonnull %4)
114-
br label %bat.exit
115-
116-
bat.exit: ; preds = %baz.exit, %print.i2
103+
define i32 @quuz() {
104+
%1 = call i32 @baz()
105+
%2 = call i32 @bat()
106+
%3 = add i32 %1, %2
107+
%4 = icmp eq i32 %3, 0
108+
br i1 %4, label %then, label %else
109+
110+
then: ; preds = %0
111+
br label %end
112+
113+
else: ; preds = %0
114+
br label %end
115+
116+
end: ; preds = %else, %then
117117
ret i32 5
118118
}
119119

120-
define noundef i32 @quux() local_unnamed_addr {
121-
end:
122-
%0 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
123-
%.not.i = icmp eq ptr %0, null
124-
br i1 %.not.i, label %bat.exit, label %print.i
125-
126-
print.i: ; preds = %end
127-
tail call void (ptr, ...) @fprintf(ptr nonnull %0, ptr nonnull @1, i32 0)
128-
%1 = tail call i32 @fclose(ptr nonnull %0)
129-
br label %bat.exit
120+
define i32 @quux() {
121+
%1 = call i32 @bat()
122+
%2 = call i32 @bat()
123+
%3 = add i32 %1, %2
124+
%4 = icmp eq i32 %3, 0
125+
br i1 %4, label %then, label %else
130126

131-
bat.exit: ; preds = %end, %print.i
132-
%2 = tail call ptr @fopen(ptr nonnull @2, ptr nonnull @3)
133-
%.not.i1 = icmp eq ptr %2, null
134-
br i1 %.not.i1, label %bat.exit3, label %print.i2
127+
then: ; preds = %0
128+
br label %end
135129

136-
print.i2: ; preds = %bat.exit
137-
tail call void (ptr, ...) @fprintf(ptr nonnull %2, ptr nonnull @1, i32 0)
138-
%3 = tail call i32 @fclose(ptr nonnull %2)
139-
br label %bat.exit3
130+
else: ; preds = %0
131+
br label %end
140132

141-
bat.exit3: ; preds = %bat.exit, %print.i2
133+
end: ; preds = %else, %then
142134
ret i32 5
143135
}
144136

145-
; Function Attrs: nofree nounwind
146-
declare noalias noundef ptr @fopen(ptr nocapture noundef readonly, ptr nocapture noundef readonly) local_unnamed_addr #1
147-
148-
declare void @fprintf(ptr, ...) local_unnamed_addr
137+
declare ptr @fopen(ptr, ptr)
149138

150-
; Function Attrs: nofree nounwind
151-
declare noundef i32 @fclose(ptr nocapture noundef) local_unnamed_addr #1
139+
declare void @fprintf(ptr, ...)
152140

153-
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
154-
attributes #1 = { nofree nounwind }
141+
declare i32 @fclose(ptr)

0 commit comments

Comments
 (0)