static CORE_ADDR gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc) { CORE_ADDR real_stop_pc, method_stop_pc; struct gdbarch *gdbarch = get_frame_arch (frame); struct minimal_symbol *thunk_sym, *fn_sym; struct obj_section *section; char *thunk_name, *fn_name; real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc); if (real_stop_pc == 0) real_stop_pc = stop_pc; /* Find the linker symbol for this potential thunk. */ thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc); section = find_pc_section (real_stop_pc); if (thunk_sym == NULL || section == NULL) return 0; /* The symbol's demangled name should be something like "virtual thunk to FUNCTION", where FUNCTION is the name of the function being thunked to. */ thunk_name = SYMBOL_DEMANGLED_NAME (thunk_sym); if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL) return 0; fn_name = strstr (thunk_name, " thunk to ") + strlen (" thunk to "); fn_sym = lookup_minimal_symbol (fn_name, NULL, section->objfile); if (fn_sym == NULL) return 0; method_stop_pc = SYMBOL_VALUE_ADDRESS (fn_sym); real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, method_stop_pc); if (real_stop_pc == 0) real_stop_pc = method_stop_pc; return real_stop_pc; }
/* Determine if we are currently in the Objective-C dispatch function. If so, get the address of the method function that the dispatcher would call and use that as the function to step into instead. Also skip over the trampoline for the function (if any). This is better for the user since they are only interested in stepping into the method function anyway. */ static CORE_ADDR objc_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc) { struct gdbarch *gdbarch = get_frame_arch (frame); CORE_ADDR real_stop_pc; CORE_ADDR method_stop_pc; real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc); if (real_stop_pc != 0) find_objc_msgcall (real_stop_pc, &method_stop_pc); else find_objc_msgcall (stop_pc, &method_stop_pc); if (method_stop_pc) { real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, method_stop_pc); if (real_stop_pc == 0) real_stop_pc = method_stop_pc; } return real_stop_pc; }