static void done_context_attach(int error, Context * ctx, void * data) { ContextAttachArgs * args = (ContextAttachArgs *)data; args->done(error, ctx, args->data); assert(error || args->process != get_context_handle(ctx)); CloseHandle(args->thread); CloseHandle(args->process); loc_free(args); }
static int get_type_info(const Symbol * sym, IMAGEHLP_SYMBOL_TYPE_INFO info_tag, void * info) { HANDLE process = get_context_handle(sym->ctx->parent == NULL ? sym->ctx : sym->ctx->parent); if (!SymGetTypeInfo(process, sym->module, sym->index, info_tag, info)) { set_win32_errno(GetLastError()); return -1; } return 0; }
static int get_sym_info(const Symbol * sym, DWORD index, SYMBOL_INFO ** res) { static ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; SYMBOL_INFO * info = (SYMBOL_INFO *)buffer; HANDLE process = get_context_handle(sym->ctx->parent == NULL ? sym->ctx : sym->ctx->parent); info->SizeOfStruct = sizeof(SYMBOL_INFO); info->MaxNameLen = MAX_SYM_NAME; if (!SymFromIndex(process, sym->module, index, info)) { set_win32_errno(GetLastError()); return -1; } *res = info; return 0; }
int enumerate_symbols(Context * ctx, int frame, EnumerateSymbolsCallBack * call_back, void * args) { ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; SYMBOL_INFO * symbol = (SYMBOL_INFO *)buffer; IMAGEHLP_STACK_FRAME stack_frame; EnumerateSymbolsContext enum_context; HANDLE process = get_context_handle(ctx->parent == NULL ? ctx : ctx->parent); symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = MAX_SYM_NAME; if (frame == STACK_TOP_FRAME) frame = get_top_frame(ctx); if (frame == STACK_TOP_FRAME) return -1; if (get_stack_frame(ctx, frame, 0, &stack_frame) < 0) return -1; if (!SymSetContext(process, &stack_frame, NULL)) { DWORD err = GetLastError(); if (err == ERROR_SUCCESS) { /* Don't know why Windows does that */ } else { set_win32_errno(err); return -1; } } enum_context.ctx = ctx; enum_context.frame = frame; enum_context.call_back = call_back; enum_context.args = args; if (!SymEnumSymbols(process, 0, NULL, enumerate_symbols_proc, &enum_context)) { set_win32_errno(GetLastError()); return -1; } return 0; }
static int find_pe_symbol_by_addr(Context * ctx, int frame, ContextAddress addr, Symbol * sym) { HANDLE process = get_context_handle(ctx->parent == NULL ? ctx : ctx->parent); ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; SYMBOL_INFO * info = (SYMBOL_INFO *)buffer; IMAGEHLP_STACK_FRAME stack_frame; DWORD err; if (set_pe_context(ctx, frame, 0, process, &stack_frame) < 0) return -1; memset(info, 0, sizeof(SYMBOL_INFO)); info->SizeOfStruct = sizeof(SYMBOL_INFO); info->MaxNameLen = MAX_SYM_NAME; if (SymFromAddr(process, addr, NULL, info)) { syminfo2symbol(ctx, frame, info, sym); return 0; } set_win32_errno(err = GetLastError()); if (err == 0 || err == ERROR_MOD_NOT_FOUND || err == ERROR_INVALID_ADDRESS) { errno = ERR_SYM_NOT_FOUND; } return -1; }
static int find_pe_symbol_by_name(Context * ctx, int frame, ContextAddress ip, char * name, Symbol * sym) { HANDLE process = get_context_handle(ctx->parent == NULL ? ctx : ctx->parent); ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; SYMBOL_INFO * info = (SYMBOL_INFO *)buffer; IMAGEHLP_STACK_FRAME stack_frame; DWORD err; if (set_pe_context(ctx, frame, ip, process, &stack_frame) < 0) return -1; memset(info, 0, sizeof(SYMBOL_INFO)); info->SizeOfStruct = sizeof(SYMBOL_INFO); info->MaxNameLen = MAX_SYM_NAME; if (find_cache_symbol(ctx, frame, stack_frame.InstructionOffset, name, sym)) return errno ? -1 : 0; /* TODO: SymFromName() searches only main executable, need to search DLLs too */ if (SymFromName(process, name, info) && info->Tag != SymTagPublicSymbol) { syminfo2symbol(ctx, frame, info, sym); add_cache_symbol(ctx, stack_frame.InstructionOffset, name, sym, 0); return 0; } if (stack_frame.InstructionOffset != 0) { DWORD64 module = SymGetModuleBase64(process, stack_frame.InstructionOffset); if (module != 0 && SymGetTypeFromName(process, module, name, info)) { syminfo2symbol(ctx, frame, info, sym); add_cache_symbol(ctx, stack_frame.InstructionOffset, name, sym, 0); return 0; } } set_win32_errno(err = GetLastError()); if (err == 0 || err == ERROR_MOD_NOT_FOUND) { add_cache_symbol(ctx, stack_frame.InstructionOffset, name, NULL, ERR_SYM_NOT_FOUND); errno = ERR_SYM_NOT_FOUND; } return -1; }