X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/56a6dfb9deeb261da2dc2462ead99844ef865e4f..953836b25a7f7ffb712d3b32e62e43885d5ef3f3:/gdb/rs6000-tdep.c diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 4b07b5d8bb..3fd0794f22 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1319,7 +1319,8 @@ rs6000_frame_saved_pc (struct frame_info *fi) { CORE_ADDR func_start; struct rs6000_framedata fdata; - int wordsize = TDEP->wordsize; + struct gdbarch_tdep *tdep = TDEP; + int wordsize = tdep->wordsize; if (fi->signal_handler_caller) return read_memory_addr (fi->frame + SIG_FRAME_PC_OFFSET, wordsize); @@ -1342,7 +1343,7 @@ rs6000_frame_saved_pc (struct frame_info *fi) return read_memory_addr (fi->next->frame + SIG_FRAME_LR_OFFSET, wordsize); else - return read_memory_addr (FRAME_CHAIN (fi) + DEFAULT_LR_SAVE, + return read_memory_addr (FRAME_CHAIN (fi) + tdep->lr_frame_offset, wordsize); } @@ -1487,41 +1488,22 @@ frame_initial_stack_address (struct frame_info *fi) return fi->extra_info->initial_sp; } - /* This function has an alloca register. If this is the top-most frame - (with the lowest address), the value in alloca register is good. */ - - if (!fi->next) - return fi->extra_info->initial_sp = read_register (fdata.alloca_reg); - - /* Otherwise, this is a caller frame. Callee has usually already saved - registers, but there are exceptions (such as when the callee - has no parameters). Find the address in which caller's alloca - register is saved. */ - - for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) - { - - if (!callee_fi->saved_regs) - frame_get_saved_regs (callee_fi, NULL); - - /* this is the address in which alloca register is saved. */ - - tmpaddr = callee_fi->saved_regs[fdata.alloca_reg]; - if (tmpaddr) - { - fi->extra_info->initial_sp = - read_memory_addr (tmpaddr, TDEP->wordsize); - return fi->extra_info->initial_sp; - } - - /* Go look into deeper levels of the frame chain to see if any one of - the callees has saved alloca register. */ - } - - /* If alloca register was not saved, by the callee (or any of its callees) - then the value in the register is still good. */ - - fi->extra_info->initial_sp = read_register (fdata.alloca_reg); + /* There is an alloca register, use its value, in the current frame, + as the initial stack pointer. */ + { + char *tmpbuf = alloca (MAX_REGISTER_RAW_SIZE); + if (frame_register_read (fi, fdata.alloca_reg, tmpbuf)) + { + fi->extra_info->initial_sp + = extract_unsigned_integer (tmpbuf, + REGISTER_RAW_SIZE (fdata.alloca_reg)); + } + else + /* NOTE: cagney/2002-04-17: At present the only time + frame_register_read will fail is when the register isn't + available. If that does happen, use the frame. */ + fi->extra_info->initial_sp = fi->frame; + } return fi->extra_info->initial_sp; } @@ -1729,7 +1711,7 @@ rs6000_do_altivec_registers (int regnum) print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout); /* Get the data in raw format. */ - if (read_relative_register_raw_bytes (i, raw_buffer)) + if (!frame_register_read (selected_frame, i, raw_buffer)) { printf_filtered ("*value not available*\n"); continue; @@ -1826,7 +1808,7 @@ rs6000_do_registers_info (int regnum, int fpregs) print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout); /* Get the data in raw format. */ - if (read_relative_register_raw_bytes (i, raw_buffer)) + if (!frame_register_read (selected_frame, i, raw_buffer)) { printf_filtered ("*value not available*\n"); continue; @@ -2075,7 +2057,7 @@ rs6000_convert_from_func_ptr_addr (CORE_ADDR addr) /* UISA-level SPRs for PowerPC. */ #define PPC_UISA_SPRS \ - /* 66 */ R4(cr), R(lr), R(ctr), R4(xer), R0 + /* 66 */ R4(cr), R(lr), R(ctr), R4(xer), R4(fpscr) /* Segment registers, for PowerPC. */ #define PPC_SEGMENT_REGS \ @@ -2109,7 +2091,8 @@ rs6000_convert_from_func_ptr_addr (CORE_ADDR addr) static const struct reg registers_power[] = { COMMON_UISA_REGS, - /* 66 */ R4(cnd), R(lr), R(cnt), R4(xer), R4(mq) + /* 66 */ R4(cnd), R(lr), R(cnt), R4(xer), R4(mq), + /* 71 */ R4(fpscr) }; /* PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only @@ -2326,11 +2309,21 @@ static const struct variant variants[] = {"7400", "Motorola/IBM PowerPC 7400 (G4)", bfd_arch_powerpc, bfd_mach_ppc_7400, num_registers (registers_7400), registers_7400}, - /* FIXME: I haven't checked the register sets of the following. */ + /* 64-bit */ + {"powerpc64", "PowerPC 64-bit user-level", bfd_arch_powerpc, + bfd_mach_ppc64, num_registers (registers_powerpc), registers_powerpc}, {"620", "Motorola PowerPC 620", bfd_arch_powerpc, bfd_mach_ppc_620, num_registers (registers_powerpc), registers_powerpc}, + {"630", "Motorola PowerPC 630", bfd_arch_powerpc, + bfd_mach_ppc_630, num_registers (registers_powerpc), registers_powerpc}, {"a35", "PowerPC A35", bfd_arch_powerpc, bfd_mach_ppc_a35, num_registers (registers_powerpc), registers_powerpc}, + {"rs64ii", "PowerPC rs64ii", bfd_arch_powerpc, + bfd_mach_ppc_rs64ii, num_registers (registers_powerpc), registers_powerpc}, + {"rs64iii", "PowerPC rs64iii", bfd_arch_powerpc, + bfd_mach_ppc_rs64iii, num_registers (registers_powerpc), registers_powerpc}, + + /* FIXME: I haven't checked the register sets of the following. */ {"rs1", "IBM POWER RS1", bfd_arch_rs6000, bfd_mach_rs6k_rs1, num_registers (registers_power), registers_power}, {"rsc", "IBM POWER RSC", bfd_arch_rs6000, @@ -2488,7 +2481,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } else { - wordsize = 4; + if (info.bfd_arch_info != NULL && info.bfd_arch_info->bits_per_word != 0) + wordsize = info.bfd_arch_info->bits_per_word / + info.bfd_arch_info->bits_per_byte; + else + wordsize = 4; } /* Find a candidate among extant architectures. */ @@ -2547,8 +2544,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_xer_regnum = 69; if (v->mach == bfd_mach_ppc_601) tdep->ppc_mq_regnum = 124; - else + else if (power) tdep->ppc_mq_regnum = 70; + else + tdep->ppc_mq_regnum = -1; + tdep->ppc_fpscr_regnum = power ? 71 : 70; if (v->arch == bfd_arch_powerpc) switch (v->mach) @@ -2567,7 +2567,15 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; } - /* Calculate byte offsets in raw register array. */ + /* Set lr_frame_offset. */ + if (wordsize == 8) + tdep->lr_frame_offset = 16; + else if (sysv_abi) + tdep->lr_frame_offset = 4; + else + tdep->lr_frame_offset = 8; + + /* Calculate byte offsets in raw register array. */ tdep->regoff = xmalloc (v->nregs * sizeof (int)); for (i = off = 0; i < v->nregs; i++) { @@ -2640,7 +2648,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_extract_return_value (gdbarch, rs6000_extract_return_value); - if (sysv_abi) + /* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments() + is correct for the SysV ABI when the wordsize is 8, but I'm also + fairly certain that ppc_sysv_abi_push_arguments() will give even + worse results since it only works for 32-bit code. So, for the moment, + we're better off calling rs6000_push_arguments() since it works for + 64-bit code. At some point in the future, this matter needs to be + revisited. */ + if (sysv_abi && wordsize == 4) set_gdbarch_push_arguments (gdbarch, ppc_sysv_abi_push_arguments); else set_gdbarch_push_arguments (gdbarch, rs6000_push_arguments); @@ -2681,7 +2696,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); - if (osabi == ELFOSABI_LINUX) + /* Note: kevinb/2002-04-12: See note above regarding *_push_arguments(). + The same remarks hold for the methods below. */ + if (osabi == ELFOSABI_LINUX && wordsize == 4) { set_gdbarch_frameless_function_invocation (gdbarch, ppc_linux_frameless_function_invocation);