/* * Invalidate all symbols that are not alive at sampling start time. */ static void invalidate_earlybirds(unsigned long long start_time) { u32 i; int flag; struct jitentry * a; flag = 0; for (i = 0; i < entry_count; i++) { a = entries_address_ascending[i]; if (a->life_end < start_time) { invalidate_entry(a); flag = 1; } } if (flag) { resort_address(); resort_symbol(); } }
static void invalidate_zero_size_entries(void) { u32 i; int flag; struct jitentry * a; flag = 0; for (i = 0; i < entry_count; i++) { a = entries_address_ascending[i]; if (a->code_size == 0) { invalidate_entry(a); flag = 1; } } if (flag) { resort_address(); resort_symbol(); } }
static bool invalidate_entries(TALLOC_CTX *ctx, struct sss_domain_info *dinfo, enum sss_cache_entry entry_type, const char *filter, const char *name) { const char *attrs[] = {SYSDB_NAME, NULL}; size_t msg_count; struct ldb_message **msgs; const char *type_string = "unknown"; errno_t ret = EINVAL; int i; const char *c_name; bool iret; if (!filter) return false; switch (entry_type) { case TYPE_USER: type_string = "user"; ret = sysdb_search_users(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_GROUP: type_string = "group"; ret = sysdb_search_groups(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_NETGROUP: type_string = "netgroup"; ret = sysdb_search_netgroups(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_SERVICE: type_string = "service"; ret = sysdb_search_services(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_AUTOFSMAP: type_string = "autofs map"; ret = search_autofsmaps(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; } if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "'%s' %s: Not found in domain '%s'\n", type_string, name ? name : "", dinfo->name); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Searching for %s in domain %s with filter %s failed\n", type_string, dinfo->name, filter); } return false; } iret = true; for (i = 0; i < msg_count; i++) { c_name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (c_name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Something bad happened, can't find attribute %s", SYSDB_NAME); ERROR("Couldn't invalidate %1$s", type_string); iret = false; } else { ret = invalidate_entry(ctx, dinfo, c_name, entry_type); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't invalidate %s %s", type_string, c_name); ERROR("Couldn't invalidate %1$s %2$s", type_string, c_name); iret = false; } } } talloc_zfree(msgs); return iret; }
/* * We decided to keep one entry in favor of the other. Instead of dropping * the overlapping entry we split or truncate it to not overlap any more. * * Looking on the address regions, we may have the following situation: * * split: |------------| * keep: |---| * * The split entry may be splitted in a left part and a right part. E.g.: * * split0/1: |--| |---| * keep: |---| * * However, both parts may or may not exist. */ static void split_entry(struct jitentry * split, struct jitentry const * keep) { unsigned long long start_addr_keep = keep->vma; unsigned long long end_addr_keep = keep->vma + keep->code_size; unsigned long long end_addr_split = split->vma + split->code_size; unsigned long long start_addr_split = split->vma; // do we need a right part? if (end_addr_split > end_addr_keep) { struct jitentry * new_entry = xcalloc(1, sizeof(struct jitentry)); char * s = NULL; /* Check for max. length to avoid possible integer overflow. */ if (strlen(split->symbol_name) > SIZE_MAX - 3) { fprintf(stderr, "Length of symbol name is too large.\n"); exit(EXIT_FAILURE); } else { s = xmalloc(strlen(split->symbol_name) + 3); strcpy(s, split->symbol_name); strcat(s, "#1"); } new_entry->vma = end_addr_keep; new_entry->code_size = end_addr_split - end_addr_keep; new_entry->symbol_name = s; new_entry->sym_name_malloced = 1; new_entry->life_start = split->life_start; new_entry->life_end = split->life_end; // the right part does not have an associated code, because we // don't know whether the split part begins at an opcode new_entry->code = NULL; verbprintf(debug, "split right (new) name=%s, start=%llx," " end=%llx\n", new_entry->symbol_name, new_entry->vma, new_entry->vma + new_entry->code_size); insert_entry(new_entry); } // do we need a left part? if (start_addr_split < start_addr_keep) { char * s = NULL; /* Check for max. length to avoid possible integer overflow. */ if (strlen(split->symbol_name) > SIZE_MAX - 3) { fprintf(stderr, "Length of symbol name is too large.\n"); exit(EXIT_FAILURE); } else { s = xmalloc(strlen(split->symbol_name) + 3); strcpy(s, split->symbol_name); strcat(s, "#0"); } split->code_size = start_addr_keep - start_addr_split; if (split->sym_name_malloced) free(split->symbol_name); split->symbol_name = s; split->sym_name_malloced = 1; verbprintf(debug, "split left name=%s, start=%llx, end=%llx\n", split->symbol_name, split->vma, split->vma + split->code_size); } else { invalidate_entry(split); } }