llvm.org GIT mirror llvm / b2d2590
[ASan] Collect unmangled names of global variables in Clang to print them in error reports. Currently ASan instrumentation pass creates a string with global name for each instrumented global (to include global names in the error report). Global name is already mangled at this point, and we may not be able to demangle it at runtime (e.g. there is no __cxa_demangle on Android). Instead, create a string with fully qualified global name in Clang, and pass it to ASan instrumentation pass in llvm.asan.globals metadata. If there is no metadata for some global, ASan will use the original algorithm. This fixes https://code.google.com/p/address-sanitizer/issues/detail?id=264. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212872 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Samsonov 5 years ago
4 changed file(s) with 39 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
215215 class GlobalsMetadata {
216216 public:
217217 struct Entry {
218 Entry() : SourceLoc(nullptr), IsDynInit(false), IsBlacklisted(false) {}
218 Entry()
219 : SourceLoc(nullptr), Name(nullptr), IsDynInit(false),
220 IsBlacklisted(false) {}
219221 GlobalVariable *SourceLoc;
222 GlobalVariable *Name;
220223 bool IsDynInit;
221224 bool IsBlacklisted;
222225 };
231234 return;
232235 for (auto MDN : Globals->operands()) {
233236 // Metadata node contains the global and the fields of "Entry".
234 assert(MDN->getNumOperands() == 4);
237 assert(MDN->getNumOperands() == 5);
235238 Value *V = MDN->getOperand(0);
236239 // The optimizer may optimize away a global entirely.
237240 if (!V)
245248 E.SourceLoc = GVLoc;
246249 addSourceLocationGlobal(GVLoc);
247250 }
248 ConstantInt *IsDynInit = cast(MDN->getOperand(2));
251 if (Value *Name = MDN->getOperand(2)) {
252 GlobalVariable *GVName = cast(Name);
253 E.Name = GVName;
254 InstrumentationGlobals.insert(GVName);
255 }
256 ConstantInt *IsDynInit = cast(MDN->getOperand(3));
249257 E.IsDynInit |= IsDynInit->isOne();
250 ConstantInt *IsBlacklisted = cast(MDN->getOperand(3));
258 ConstantInt *IsBlacklisted = cast(MDN->getOperand(4));
251259 E.IsBlacklisted |= IsBlacklisted->isOne();
252260 }
253261 }
10481056 for (size_t i = 0; i < n; i++) {
10491057 static const uint64_t kMaxGlobalRedzone = 1 << 18;
10501058 GlobalVariable *G = GlobalsToChange[i];
1059
1060 auto MD = GlobalsMD.get(G);
1061 // Create string holding the global name unless it was provided by
1062 // the metadata.
1063 GlobalVariable *Name =
1064 MD.Name ? MD.Name : createPrivateGlobalForString(M, G->getName(),
1065 /*AllowMerging*/ true);
1066
10511067 PointerType *PtrTy = cast(G->getType());
10521068 Type *Ty = PtrTy->getElementType();
10531069 uint64_t SizeInBytes = DL->getTypeAllocSize(Ty);
10691085 NewTy, G->getInitializer(),
10701086 Constant::getNullValue(RightRedZoneTy), NULL);
10711087
1072 GlobalVariable *Name =
1073 createPrivateGlobalForString(M, G->getName(), /*AllowMerging*/true);
1074
10751088 // Create a new global variable with enough space for a redzone.
10761089 GlobalValue::LinkageTypes Linkage = G->getLinkage();
10771090 if (G->isConstant() && Linkage == GlobalValue::PrivateLinkage)
10901103 ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true));
10911104 NewGlobal->takeName(G);
10921105 G->eraseFromParent();
1093
1094 auto MD = GlobalsMD.get(G);
10951106
10961107 Initializers[i] = ConstantStruct::get(
10971108 GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
1717 @.asan_loc_descr2 = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* @.str1, i32 12, i32 14 }
1818 @.asan_loc_descr4 = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* @.str1, i32 14, i32 25 }
1919
20 ; Global names:
21 @.str2 = private unnamed_addr constant [7 x i8] c"global\00", align 1
22 @.str3 = private unnamed_addr constant [16 x i8] c"dyn_init_global\00", align 1
23 @.str4 = private unnamed_addr constant [11 x i8] c"static_var\00", align 1
24 @.str5 = private unnamed_addr constant [17 x i8] c"\00", align 1
25
2026 ; Check that globals were instrumented, but sanitizer location descriptors weren't:
2127 ; CHECK: @global = global { i32, [60 x i8] } zeroinitializer, align 32
2228 ; CHECK: @.str = internal unnamed_addr constant { [14 x i8], [50 x i8] } { [14 x i8] c"Hello, world!\00", [50 x i8] zeroinitializer }, align 32
2329 ; CHECK: @.asan_loc_descr = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* @.str1, i32 5, i32 5 }
30 ; CHECK: @.str2 = private unnamed_addr constant [7 x i8] c"global\00", align 1
2431
25 ; Check that location decriptors were passed into __asan_register_globals:
32 ; Check that location decriptors and global names were passed into __asan_register_globals:
33 ; CHECK: i64 ptrtoint ([7 x i8]* @.str2 to i64)
2634 ; CHECK: i64 ptrtoint ({ [22 x i8]*, i32, i32 }* @.asan_loc_descr to i64)
2735
2836 ; Function Attrs: nounwind sanitize_address
5462 !llvm.asan.globals = !{!0, !1, !2, !3, !4}
5563 !llvm.ident = !{!5}
5664
57 !0 = metadata !{i32* @global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr, i1 false, i1 false}
58 !1 = metadata !{i32* @dyn_init_global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr1, i1 true, i1 false}
59 !2 = metadata !{i32* @blacklisted_global, null, i1 false, i1 true}
60 !3 = metadata !{i32* @_ZZ4funcvE10static_var, { [22 x i8]*, i32, i32 }* @.asan_loc_descr2, i1 false, i1 false}
61 !4 = metadata !{[14 x i8]* @.str, { [22 x i8]*, i32, i32 }* @.asan_loc_descr4, i1 false, i1 false}
65 !0 = metadata !{i32* @global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr, [7 x i8]* @.str2, i1 false, i1 false}
66 !1 = metadata !{i32* @dyn_init_global, { [22 x i8]*, i32, i32 }* @.asan_loc_descr1, [16 x i8]* @.str3, i1 true, i1 false}
67 !2 = metadata !{i32* @blacklisted_global, null, null, i1 false, i1 true}
68 !3 = metadata !{i32* @_ZZ4funcvE10static_var, { [22 x i8]*, i32, i32 }* @.asan_loc_descr2, [11 x i8]* @.str4, i1 false, i1 false}
69 !4 = metadata !{[14 x i8]* @.str, { [22 x i8]*, i32, i32 }* @.asan_loc_descr4, [17 x i8]* @.str5, i1 false, i1 false}
6270 !5 = metadata !{metadata !"clang version 3.5.0 (211282)"}
6868
6969
7070 !llvm.asan.globals = !{!0}
71 !0 = metadata !{[10 x i32]* @GlobDy, null, i1 true, i1 false}
71 !0 = metadata !{[10 x i32]* @GlobDy, null, null, i1 true, i1 false}
7272
7373 ; CHECK-LABEL: define internal void @asan.module_ctor
7474 ; CHECK-NOT: ret
66 @YYY = global i32 0, align 4 ; W/o dynamic initializer.
77 ; Clang will emit the following metadata identifying @xxx as dynamically
88 ; initialized.
9 !0 = metadata !{i32* @xxx, null, i1 true, i1 false}
10 !1 = metadata !{i32* @XXX, null, i1 true, i1 false}
11 !2 = metadata !{i32* @yyy, null, i1 false, i1 false}
12 !3 = metadata !{i32* @YYY, null, i1 false, i1 false}
9 !0 = metadata !{i32* @xxx, null, null, i1 true, i1 false}
10 !1 = metadata !{i32* @XXX, null, null, i1 true, i1 false}
11 !2 = metadata !{i32* @yyy, null, null, i1 false, i1 false}
12 !3 = metadata !{i32* @YYY, null, null, i1 false, i1 false}
1313 !llvm.asan.globals = !{!0, !1, !2, !3}
1414
1515 define i32 @initializer() uwtable {