#include "objfiles.h"
#include "arch-utils.h"
#include "regcache.h"
+#include "doublest.h"
+#include "value.h"
#include "bfd/libbfd.h" /* for bfd_default_set_arch_mach */
#include "coff/internal.h" /* for libcoff.h */
#include "elf-bfd.h"
+#include "solib-svr4.h"
#include "ppc-tdep.h"
/* If the kernel has to deliver a signal, it pushes a sigcontext
/* 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
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;
}
}
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
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;
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;
for (; jj < nargs; ++jj)
{
- value_ptr val = args[jj];
+ struct value *val = args[jj];
space += ((TYPE_LENGTH (VALUE_TYPE (val))) + 3) & -4;
}
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[] =
{
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)
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)
}
else
{
- tdep = TDEP;
- if (tdep)
- wordsize = tdep->wordsize;
- else
- wordsize = 4;
+ wordsize = 4;
}
/* Find a candidate among extant architectures. */
if (!from_xcoff_exec)
{
- arch = info.bfd_architecture;
+ arch = info.bfd_arch_info->arch;
mach = info.bfd_arch_info->mach;
}
else
set_gdbarch_memory_remove_breakpoint (gdbarch,
ppc_linux_memory_remove_breakpoint);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
}
else
{