static CORE_ADDR ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { unsigned int insnbuf[POWERPC32_PLT_STUB_LEN]; struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR target = 0; if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf)) { /* Insn pattern is lis r11, xxxx lwz r11, xxxx(r11) Branch target is in r11. */ target = (ppc_insn_d_field (insnbuf[0]) << 16) | ppc_insn_d_field (insnbuf[1]); target = read_memory_unsigned_integer (target, 4, byte_order); } if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf)) { /* Insn pattern is lwz r11, xxxx(r30) Branch target is in r11. */ target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30) + ppc_insn_d_field (insnbuf[0]); target = read_memory_unsigned_integer (target, 4, byte_order); } return target; }
CORE_ADDR ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { #define MAX(a,b) ((a) > (b) ? (a) : (b)) unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), ARRAY_SIZE (ppc64_standard_linkage2)), ARRAY_SIZE (ppc64_standard_linkage3)) - 1]; CORE_ADDR target; if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) && (insns[8] != 0 || insns[9] != 0)) pc = ppc64_standard_linkage3_target (frame, pc, insns); else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns) && (insns[10] != 0 || insns[11] != 0)) pc = ppc64_standard_linkage2_target (frame, pc, insns); else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns)) pc = ppc64_standard_linkage1_target (frame, pc, insns); else return 0; /* The PLT descriptor will either point to the already resolved target address, or else to a glink stub. As the latter carry synthetic @plt symbols, find_solib_trampoline_target should be able to resolve them. */ target = find_solib_trampoline_target (frame, pc); return target ? target : pc; }
static CORE_ADDR ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc) { #define MAX(a,b) ((a) > (b) ? (a) : (b)) unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), ARRAY_SIZE (ppc64_standard_linkage2)), MAX (ARRAY_SIZE (ppc64_standard_linkage3), ARRAY_SIZE (ppc64_standard_linkage4))), MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5), ARRAY_SIZE (ppc64_standard_linkage6)), MAX (ARRAY_SIZE (ppc64_standard_linkage7), ARRAY_SIZE (ppc64_standard_linkage8)))) - 1]; CORE_ADDR target; int scan_limit, i; scan_limit = 1; /* When reverse-debugging, scan backward to check whether we are in the middle of trampoline code. */ if (execution_direction == EXEC_REVERSE) scan_limit = ARRAY_SIZE (insns) - 1; for (i = 0; i < scan_limit; i++) { if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns)) pc = ppc64_standard_linkage4_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns)) pc = ppc64_standard_linkage3_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns)) pc = ppc64_standard_linkage4_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns) && (insns[8] != 0 || insns[9] != 0)) pc = ppc64_standard_linkage3_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns) && (insns[9] != 0 || insns[10] != 0)) pc = ppc64_standard_linkage4_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns) && (insns[8] != 0 || insns[9] != 0)) pc = ppc64_standard_linkage3_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns) && (insns[10] != 0 || insns[11] != 0)) pc = ppc64_standard_linkage2_target (frame, insns); else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1 && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns)) pc = ppc64_standard_linkage1_target (frame, insns); else { /* Scan backward one more instructions if doesn't match. */ pc -= 4; continue; } /* The PLT descriptor will either point to the already resolved target address, or else to a glink stub. As the latter carry synthetic @plt symbols, find_solib_trampoline_target should be able to resolve them. */ target = find_solib_trampoline_target (frame, pc); return target ? target : pc; } return 0; }