@@ -96,14 +96,15 @@ static const char *const kAsanPoisonGlobalsName = "__asan_before_dynamic_init";
96
96
static const char *const kAsanUnpoisonGlobalsName = " __asan_after_dynamic_init" ;
97
97
static const char *const kAsanInitName = " __asan_init" ;
98
98
static const char *const kAsanVersionCheckName =
99
- " __asan_version_mismatch_check_v6 " ;
99
+ " __asan_version_mismatch_check_v7 " ;
100
100
static const char *const kAsanPtrCmp = " __sanitizer_ptr_cmp" ;
101
101
static const char *const kAsanPtrSub = " __sanitizer_ptr_sub" ;
102
102
static const char *const kAsanHandleNoReturnName = " __asan_handle_no_return" ;
103
103
static const int kMaxAsanStackMallocSizeClass = 10 ;
104
104
static const char *const kAsanStackMallocNameTemplate = " __asan_stack_malloc_" ;
105
105
static const char *const kAsanStackFreeNameTemplate = " __asan_stack_free_" ;
106
106
static const char *const kAsanGenPrefix = " __asan_gen_" ;
107
+ static const char *const kODRGenPrefix = " __odr_asan_gen_" ;
107
108
static const char *const kSanCovGenPrefix = " __sancov_gen_" ;
108
109
static const char *const kAsanPoisonStackMemoryName =
109
110
" __asan_poison_stack_memory" ;
@@ -229,6 +230,12 @@ static cl::opt<uint32_t> ClForceExperiment(
229
230
cl::desc (" Force optimization experiment (for testing)" ), cl::Hidden,
230
231
cl::init(0 ));
231
232
233
+ static cl::opt<bool >
234
+ ClUsePrivateAliasForGlobals (" asan-use-private-alias" ,
235
+ cl::desc (" Use private aliases for global"
236
+ " variables" ),
237
+ cl::Hidden, cl::init(false ));
238
+
232
239
// Debug flags.
233
240
static cl::opt<int > ClDebug (" asan-debug" , cl::desc(" debug" ), cl::Hidden,
234
241
cl::init(0 ));
@@ -823,7 +830,8 @@ static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M,
823
830
824
831
static bool GlobalWasGeneratedByAsan (GlobalVariable *G) {
825
832
return G->getName ().find (kAsanGenPrefix ) == 0 ||
826
- G->getName ().find (kSanCovGenPrefix ) == 0 ;
833
+ G->getName ().find (kSanCovGenPrefix ) == 0 ||
834
+ G->getName ().find (kODRGenPrefix ) == 0 ;
827
835
}
828
836
829
837
Value *AddressSanitizer::memToShadow (Value *Shadow, IRBuilder<> &IRB) {
@@ -1321,10 +1329,11 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
1321
1329
// const char *module_name;
1322
1330
// size_t has_dynamic_init;
1323
1331
// void *source_location;
1332
+ // size_t odr_indicator;
1324
1333
// We initialize an array of such structures and pass it to a run-time call.
1325
1334
StructType *GlobalStructTy =
1326
1335
StructType::get (IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
1327
- IntptrTy, IntptrTy, nullptr );
1336
+ IntptrTy, IntptrTy, IntptrTy, nullptr );
1328
1337
SmallVector<Constant *, 16 > Initializers (n);
1329
1338
1330
1339
bool HasDynamicallyInitializedGlobals = false ;
@@ -1340,10 +1349,11 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
1340
1349
GlobalVariable *G = GlobalsToChange[i];
1341
1350
1342
1351
auto MD = GlobalsMD.get (G);
1352
+ StringRef NameForGlobal = G->getName ();
1343
1353
// Create string holding the global name (use global name from metadata
1344
1354
// if it's available, otherwise just write the name of global variable).
1345
1355
GlobalVariable *Name = createPrivateGlobalForString (
1346
- M, MD.Name .empty () ? G-> getName () : MD.Name ,
1356
+ M, MD.Name .empty () ? NameForGlobal : MD.Name ,
1347
1357
/* AllowMerging*/ true );
1348
1358
1349
1359
Type *Ty = G->getValueType ();
@@ -1391,13 +1401,41 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
1391
1401
SourceLoc = ConstantInt::get (IntptrTy, 0 );
1392
1402
}
1393
1403
1404
+ Constant *ODRIndicator = ConstantExpr::getNullValue (IRB.getInt8PtrTy ());
1405
+ GlobalValue *InstrumentedGlobal = NewGlobal;
1406
+
1407
+ bool CanUsePrivateAliases = TargetTriple.isOSBinFormatELF ();
1408
+ if (CanUsePrivateAliases && ClUsePrivateAliasForGlobals) {
1409
+ // Create local alias for NewGlobal to avoid crash on ODR between
1410
+ // instrumented and non-instrumented libraries.
1411
+ auto *GA = GlobalAlias::create (GlobalValue::InternalLinkage,
1412
+ NameForGlobal + M.getName (), NewGlobal);
1413
+
1414
+ // With local aliases, we need to provide another externally visible
1415
+ // symbol __odr_asan_XXX to detect ODR violation.
1416
+ auto *ODRIndicatorSym =
1417
+ new GlobalVariable (M, IRB.getInt8Ty (), false , Linkage,
1418
+ Constant::getNullValue (IRB.getInt8Ty ()),
1419
+ kODRGenPrefix + NameForGlobal, nullptr ,
1420
+ NewGlobal->getThreadLocalMode ());
1421
+
1422
+ // Set meaningful attributes for indicator symbol.
1423
+ ODRIndicatorSym->setVisibility (NewGlobal->getVisibility ());
1424
+ ODRIndicatorSym->setDLLStorageClass (NewGlobal->getDLLStorageClass ());
1425
+ ODRIndicatorSym->setAlignment (1 );
1426
+ ODRIndicator = ODRIndicatorSym;
1427
+ InstrumentedGlobal = GA;
1428
+ }
1429
+
1394
1430
Initializers[i] = ConstantStruct::get (
1395
- GlobalStructTy, ConstantExpr::getPointerCast (NewGlobal, IntptrTy),
1431
+ GlobalStructTy,
1432
+ ConstantExpr::getPointerCast (InstrumentedGlobal, IntptrTy),
1396
1433
ConstantInt::get (IntptrTy, SizeInBytes),
1397
1434
ConstantInt::get (IntptrTy, SizeInBytes + RightRedzoneSize),
1398
1435
ConstantExpr::getPointerCast (Name, IntptrTy),
1399
1436
ConstantExpr::getPointerCast (ModuleName, IntptrTy),
1400
- ConstantInt::get (IntptrTy, MD.IsDynInit ), SourceLoc, nullptr );
1437
+ ConstantInt::get (IntptrTy, MD.IsDynInit ), SourceLoc,
1438
+ ConstantExpr::getPointerCast (ODRIndicator, IntptrTy), nullptr );
1401
1439
1402
1440
if (ClInitializers && MD.IsDynInit ) HasDynamicallyInitializedGlobals = true ;
1403
1441
0 commit comments