X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=82c18c1dac2e9210aba04013c97ce9ce07724731;hb=1d9d99f32d861ae85dd59689ada801cc51d3ac91;hp=efdff362ab3122c80fb26ab50054ce09404046e0;hpb=55d05f3b1df57b68c2362236d73e47e26cef3572;p=binutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index efdff362ab3..82c18c1dac2 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,5 +1,6 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. @@ -29,6 +30,8 @@ #include "symfile.h" #include "objfiles.h" #include "arch-utils.h" +#include "regcache.h" +#include "doublest.h" #include "bfd/libbfd.h" /* for bfd_default_set_arch_mach */ #include "coff/internal.h" /* for libcoff.h */ @@ -297,7 +300,8 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) /* AIX does not support PT_STEP. Simulate it. */ void -rs6000_software_single_step (unsigned int signal, int insert_breakpoints_p) +rs6000_software_single_step (enum target_signal signal, + int insert_breakpoints_p) { #define INSNLEN(OPCODE) 4 @@ -750,7 +754,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) function as well. */ tmp = find_pc_misc_function (pc); - if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, "main")) + if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, main_name ())) return pc + 8; } } @@ -842,7 +846,7 @@ rs6000_pop_frame (void) static void rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun, - int nargs, value_ptr *args, struct type *type, + int nargs, struct value **args, struct type *type, int gcc_p) { #define TOC_ADDR_OFFSET 20 @@ -875,7 +879,7 @@ rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun, starting from r4. */ static CORE_ADDR -rs6000_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp, +rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { int ii; @@ -886,7 +890,7 @@ rs6000_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp, int f_argno = 0; /* current floating point argno */ int wordsize = TDEP->wordsize; - value_ptr arg = 0; + struct value *arg = 0; struct type *type; CORE_ADDR saved_sp; @@ -1005,7 +1009,7 @@ ran_out_of_registers_for_arguments: for (; jj < nargs; ++jj) { - value_ptr val = args[jj]; + struct value *val = args[jj]; space += ((TYPE_LENGTH (VALUE_TYPE (val))) + 3) & -4; } @@ -1129,19 +1133,55 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf) static CORE_ADDR rs6000_struct_return_address; -/* Indirect function calls use a piece of trampoline code to do context - switching, i.e. to set the new TOC table. Skip such code if we are on - its first instruction (as when we have single-stepped to here). - Also skip shared library trampoline code (which is different from +/* Return whether handle_inferior_event() should proceed through code + starting at PC in function NAME when stepping. + + The AIX -bbigtoc linker option generates functions @FIX0, @FIX1, etc. to + handle memory references that are too distant to fit in instructions + generated by the compiler. For example, if 'foo' in the following + instruction: + + lwz r9,foo(r2) + + is greater than 32767, the linker might replace the lwz with a branch to + somewhere in @FIX1 that does the load in 2 instructions and then branches + back to where execution should continue. + + GDB should silently step over @FIX code, just like AIX dbx does. + Unfortunately, the linker uses the "b" instruction for the branches, + meaning that the link register doesn't get set. Therefore, GDB's usual + step_over_function() mechanism won't work. + + Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and SKIP_TRAMPOLINE_CODE hooks + in handle_inferior_event() to skip past @FIX code. */ + +int +rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name) +{ + return name && !strncmp (name, "@FIX", 4); +} + +/* Skip code that the user doesn't want to see when stepping: + + 1. Indirect function calls use a piece of trampoline code to do context + switching, i.e. to set the new TOC table. Skip such code if we are on + its first instruction (as when we have single-stepped to here). + + 2. Skip shared library trampoline code (which is different from indirect function call trampolines). + + 3. Skip bigtoc fixup code. + Result is desired PC to step until, or NULL if we are not in - trampoline code. */ + code that should be skipped. */ CORE_ADDR rs6000_skip_trampoline_code (CORE_ADDR pc) { register unsigned int ii, op; + int rel; CORE_ADDR solib_target_pc; + struct minimal_symbol *msymbol; static unsigned trampoline_code[] = { @@ -1155,6 +1195,21 @@ rs6000_skip_trampoline_code (CORE_ADDR pc) 0 }; + /* Check for bigtoc fixup code. */ + msymbol = lookup_minimal_symbol_by_pc (pc); + if (msymbol && rs6000_in_solib_return_trampoline (pc, SYMBOL_NAME (msymbol))) + { + /* Double-check that the third instruction from PC is relative "b". */ + op = read_memory_integer (pc + 8, 4); + if ((op & 0xfc000003) == 0x48000000) + { + /* Extract bits 6-29 as a signed 24-bit relative word address and + add it to the containing PC. */ + rel = ((int)(op << 6) >> 6); + return pc + 8 + rel; + } + } + /* If pc is in a shared library trampoline, return its target. */ solib_target_pc = find_solib_trampoline_target (pc); if (solib_target_pc) @@ -2039,8 +2094,9 @@ process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj) *os_ident_ptr = ELFOSABI_SOLARIS; break; default : - internal_error ( - "process_note_abi_sections: unknown OS number %d", os_number); + internal_error (__FILE__, __LINE__, + "process_note_abi_sections: unknown OS number %d", + os_number); break; } } @@ -2107,8 +2163,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) osabi = get_elfosabi (info.abfd); - /* Check word size. If INFO is from a binary file, infer it from that, - else use the previously-inferred size. */ + /* Check word size. If INFO is from a binary file, infer it from + that, else choose a likely default. */ if (from_xcoff_exec) { if (xcoff_data (info.abfd)->xcoff64) @@ -2125,11 +2181,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } else { - tdep = TDEP; - if (tdep) - wordsize = tdep->wordsize; - else - wordsize = 4; + wordsize = 4; } /* Find a candidate among extant architectures. */ @@ -2155,7 +2207,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (!from_xcoff_exec) { - arch = info.bfd_architecture; + arch = info.bfd_arch_info->arch; mach = info.bfd_arch_info->mach; } else