const void *__module_name;
uptr __has_dynamic_init;
__asan_global_source_location *__location;
- char *__odr_indicator;
} type. */
static tree
asan_global_struct (void)
{
- static const char *field_names[8]
+ static const char *field_names[]
= { "__beg", "__size", "__size_with_redzone",
- "__name", "__module_name", "__has_dynamic_init", "__location", "__odr_indicator"};
- tree fields[8], ret;
+ "__name", "__module_name", "__has_dynamic_init", "__location"};
+ tree fields[ARRAY_SIZE(field_names)], ret;
int i;
ret = make_node (RECORD_TYPE);
- for (i = 0; i < 8; i++)
+ for (i = 0; i < ARRAY_SIZE(field_names); i++)
{
fields[i]
= build_decl (UNKNOWN_LOCATION, FIELD_DECL,
else
locptr = build_int_cst (uptr, 0);
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
- /* TODO: support ODR indicators. */
- CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0));
init = build_constructor (type, vinner);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
}
REGISTERED = 1
};
-// Check ODR violation for given global G via special ODR indicator. We use
-// this method in case compiler instruments global variables through their
-// local aliases.
-static void CheckODRViolationViaIndicator(const Global *g) {
- u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
- if (*odr_indicator == UNREGISTERED) {
- *odr_indicator = REGISTERED;
- return;
- }
- // If *odr_indicator is DEFINED, some module have already registered
- // externally visible symbol with the same name. This is an ODR violation.
- for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
- if (g->odr_indicator == l->g->odr_indicator &&
- (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
- !IsODRViolationSuppressed(g->name))
- ReportODRViolation(g, FindRegistrationSite(g),
- l->g, FindRegistrationSite(l->g));
- }
-}
-
// Check ODR violation for given global G by checking if it's already poisoned.
// We use this method in case compiler doesn't use private aliases for global
// variables.
}
}
-// Clang provides two different ways for global variables protection:
-// it can poison the global itself or its private alias. In former
-// case we may poison same symbol multiple times, that can help us to
-// cheaply detect ODR violation: if we try to poison an already poisoned
-// global, we have ODR violation error.
-// In latter case, we poison each symbol exactly once, so we use special
-// indicator symbol to perform similar check.
-// In either case, compiler provides a special odr_indicator field to Global
-// structure, that can contain two kinds of values:
-// 1) Non-zero value. In this case, odr_indicator is an address of
-// corresponding indicator variable for given global.
-// 2) Zero. This means that we don't use private aliases for global variables
-// and can freely check ODR violation with the first method.
-//
-// This routine chooses between two different methods of ODR violation
-// detection.
-static inline bool UseODRIndicator(const Global *g) {
- // Use ODR indicator method iff use_odr_indicator flag is set and
- // indicator symbol address is not 0.
- return flags()->use_odr_indicator && g->odr_indicator > 0;
-}
-
// Register a global variable.
// This function may be called more than once for every global
// so we store the globals in a map.
CHECK(AddrIsAlignedByGranularity(g->beg));
}
CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
- if (flags()->detect_odr_violation) {
+ if (0 && flags()->detect_odr_violation) {
// Try detecting ODR (One Definition Rule) violation, i.e. the situation
// where two globals with the same name are defined in different modules.
- if (UseODRIndicator(g))
- CheckODRViolationViaIndicator(g);
- else
- CheckODRViolationViaPoisoning(g);
+ // NOTE: Currently ODR check is switched off in order to maintain ABI
+ // compatibility.
+ CheckODRViolationViaPoisoning(g);
}
if (CanPoisonMemory())
PoisonRedZones(*g);
// We unpoison the shadow memory for the global but we do not remove it from
// the list because that would require O(n^2) time with the current list
// implementation. It might not be worth doing anyway.
-
- // Release ODR indicator.
- if (UseODRIndicator(g)) {
- u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
- *odr_indicator = UNREGISTERED;
- }
}
void StopInitOrderChecking() {