static int simple_glob_match(unsigned char *s, unsigned char *p) { unsigned i; if (find_first_match(s, p, &i) != s) return 0; if (!p[i]) return !s[i]; while (1) { s += i; p += i + 1; if (!(s = find_first_match(s, p, &i))) return 0; if (!p[i]) { s += strlen(cast_const_char s) - i; return !!find_first_match(s, p, &i); } } }
int dbg_lookup_global_functions(QueryThread* q, JSON_Builder* builder, const char* name) { uint32_t match; dbg_wait_for_global_symbols(q); match = find_first_match(name, case_sensitive_cmp); while (match < global_symbol_count && !strcmp(global_symbols[match].name, name)) { GlobalSymbol* g = &global_symbols[match]; DebugObject* obj = &debug_objects[g->defining_object]; CH_DbgDwarf2FunctionInfo info; if (!(g->kind & AUTOCOMPLETE_KIND_GLOBAL_FUNCTION)) continue; if (!dwarf2_lookup_function_info(q, obj->dwarf_obj, g->defining_object_offset, DWARF2_FUNCTION_ALL, &info)) return 0; if (info.entry_point) { uint32_t i; for (i = 0; i < obj->num_map_events; ++i) { CH_DBAddrMapEntry* entry = get_address_map_entries() + obj->map_events[i]; if (entry->offset <= info.entry_point && info.entry_point < entry->offset + entry->length) { output_function_object(obj, g->defining_object_offset, entry, &info, builder); } } } dwarf2_destroy_function_info(&info); ++match; } return 1; }
int dbg_lookup_global_type(QueryThread* q, JSON_Builder* builder, const char* name, const char* namespace_prefix, const char* container_prefix, const char* context_typekey) { uint32_t match; CH_StringBuf full_name; char* heap_name; GlobalSymbol* best_symbol = NULL; DebugObject* context_type_object = NULL; CH_DbgDwarf2Offset context_type_offset; if (context_typekey) { if (!crack_type_key(q, context_typekey, &context_type_object, &context_type_offset)) return 0; } dbg_wait_for_global_symbols(q); stringbuf_init(&full_name); if (namespace_prefix) { stringbuf_append(&full_name, namespace_prefix); } if (container_prefix) { stringbuf_append(&full_name, container_prefix); } stringbuf_append(&full_name, name); heap_name = stringbuf_finish(&full_name); match = find_first_match(heap_name, case_sensitive_cmp); while (match < global_symbol_count && !strcmp(global_symbols[match].name, heap_name)) { GlobalSymbol* g = &global_symbols[match]; ++match; if (g->kind != AUTOCOMPLETE_KIND_GLOBAL_TYPE) continue; if (g->is_partial) continue; if (!best_symbol || lookup_global_type_score_symbol(g, context_type_object) > lookup_global_type_score_symbol(best_symbol, context_type_object)) { best_symbol = g; } } if (best_symbol) { append_type_key(builder, "typeKey", &debug_objects[best_symbol->defining_object], best_symbol->defining_object_offset); } safe_free(heap_name); return 1; }
CH_DbgCompletionResult dbg_auto_complete_global_name(QueryThread* q, CH_DbgCompletionKind kinds, const char* prefix, uint8_t case_sensitive, int32_t from, int32_t desired_count) { CH_DbgCompletionResult result; uint32_t first_match; CH_GrowBuf matches; uint32_t total_match_count; uint32_t prefix_len = strlen(prefix); uint32_t match_index; uint32_t total_chars; uint32_t match; dbg_wait_for_global_symbols(q); init_buf(&matches); /* XXX report progress? */ first_match = find_first_match(prefix, strcasecmp); /* Collect a list of all matches to be returned. Skip global symbols that don't match the search criteria and suppress duplicate name+kind pairs; symbols that have the same name and kind but are multiply defined should just have one autocomplete result. Gather more matches than we really need to get an estimate of the total number. */ match = first_match; total_match_count = 0; while (match < global_symbol_count && total_match_count < (from + desired_count)*4) { GlobalSymbol* m = &global_symbols[match]; ++match; if (strncasecmp(m->name, prefix, prefix_len)) break; if (!(m->kind & kinds)) continue; if (case_sensitive && strncmp(m->name, prefix, prefix_len)) continue; if (total_match_count > 0) { GlobalSymbol* prev_match = &global_symbols[((uint32_t*)matches.data)[total_match_count - 1]]; if (strcmp(m->name, prev_match->name) == 0 && m->kind == prev_match->kind) continue; } ensure_buffer_size(&matches, sizeof(uint32_t)*(total_match_count + 1)); ((uint32_t*)matches.data)[total_match_count] = match - 1; total_match_count++; } result.total_matches = total_match_count; result.match_count = total_match_count - from; if (result.match_count <= 0) { safe_free(matches.data); result.match_count = 0; result.match_names = NULL; result.match_kinds = NULL; return result; } if (result.match_count > desired_count) { result.match_count = desired_count; } total_chars = 0; for (match_index = 0; match_index < result.match_count; ++match_index) { uint32_t i = ((uint32_t*)matches.data)[match_index + from]; total_chars += strlen(global_symbols[i].name) + 1; } result.match_kinds = safe_malloc(sizeof(CH_DbgCompletionKind)*result.match_count); result.match_names = safe_malloc(total_chars); total_chars = 0; for (match_index = 0; match_index < result.match_count; ++match_index) { uint32_t i = ((uint32_t*)matches.data)[match_index + from]; uint32_t len = strlen(global_symbols[i].name) + 1; result.match_kinds[match_index] = global_symbols[i].kind; memcpy(result.match_names + total_chars, global_symbols[i].name, len); total_chars += len; } safe_free(matches.data); return result; }