|
|
7ab123 |
commit 591a12a1d4c8843343eb999145d8bcc1efedf408
|
|
|
7ab123 |
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
|
|
|
7ab123 |
Date: Tue Feb 4 18:44:14 2014 +0100
|
|
|
7ab123 |
|
|
|
7ab123 |
PowerPC64 ELFv2 ABI: skip global entry point code
|
|
|
7ab123 |
|
|
|
7ab123 |
This patch handles another aspect of the ELFv2 ABI, which unfortunately
|
|
|
7ab123 |
requires common code changes.
|
|
|
7ab123 |
|
|
|
7ab123 |
In ELFv2, functions may provide both a global and a local entry point.
|
|
|
7ab123 |
The global entry point (where the function symbol points to) is intended
|
|
|
7ab123 |
to be used for function-pointer or cross-module (PLT) calls, and requires
|
|
|
7ab123 |
r12 to be set up to the entry point address itself. The local entry
|
|
|
7ab123 |
point (which is found at a fixed offset after the global entry point,
|
|
|
7ab123 |
as defined by bits in the symbol table entries' st_other field), instead
|
|
|
7ab123 |
expects r2 to be set up to the current TOC.
|
|
|
7ab123 |
|
|
|
7ab123 |
Now, when setting a breakpoint on a function by name, you really want
|
|
|
7ab123 |
that breakpoint to trigger either way, no matter whether the function
|
|
|
7ab123 |
is called via its local or global entry point. Since the global entry
|
|
|
7ab123 |
point will always fall through into the local entry point, the way to
|
|
|
7ab123 |
achieve that is to simply set the breakpoint at the local entry point.
|
|
|
7ab123 |
|
|
|
7ab123 |
One way to do that would be to have prologue parsing skip the code
|
|
|
7ab123 |
sequence that makes up the global entry point. Unfortunately, this
|
|
|
7ab123 |
does not work reliably, since -for optimized code- GDB these days
|
|
|
7ab123 |
will not actuall invoke the prologue parsing code but instead just
|
|
|
7ab123 |
set the breakpoint at the symbol address and rely on DWARF being
|
|
|
7ab123 |
correct at any point throughout the function ...
|
|
|
7ab123 |
|
|
|
7ab123 |
Unfortunately, I don't really see any way to express the notion of
|
|
|
7ab123 |
local entry points with the current set of gdbarch callbacks.
|
|
|
7ab123 |
|
|
|
7ab123 |
Thus this patch adds a new callback, skip_entrypoint, that is
|
|
|
7ab123 |
somewhat analogous to skip_prologue, but is called every time
|
|
|
7ab123 |
GDB needs to determine a function start address, even in those
|
|
|
7ab123 |
cases where GDB decides to not call skip_prologue.
|
|
|
7ab123 |
|
|
|
7ab123 |
As a side effect, the skip_entrypoint implementation on ppc64
|
|
|
7ab123 |
does not need to perform any instruction parsing; it can simply
|
|
|
7ab123 |
rely on the local entry point flags in the symbol table entry.
|
|
|
7ab123 |
|
|
|
7ab123 |
With this implemented, two test cases would still fail to set
|
|
|
7ab123 |
the breakpoint correctly, but that's because they use the construct:
|
|
|
7ab123 |
|
|
|
7ab123 |
gdb_test "break *hello"
|
|
|
7ab123 |
|
|
|
7ab123 |
Now, using "*hello" explicitly instructs GDB to set the breakpoint
|
|
|
7ab123 |
at the numerical value of "hello" treated as function pointer, so
|
|
|
7ab123 |
it will by definition only hit the global entry point.
|
|
|
7ab123 |
|
|
|
7ab123 |
I think this behaviour is unavoidable, but acceptable -- most people
|
|
|
7ab123 |
do not use this construct, and if they do, they get what they
|
|
|
7ab123 |
asked for ...
|
|
|
7ab123 |
|
|
|
7ab123 |
In one of those two test cases, use of this construct is really
|
|
|
7ab123 |
not appropriate. I think this was added way back when as a means
|
|
|
7ab123 |
to work around prologue skipping problems on some platforms. These
|
|
|
7ab123 |
days that shouldn't really be necessary any more ...
|
|
|
7ab123 |
|
|
|
7ab123 |
For the other (step-bt), we really want to make sure backtracing
|
|
|
7ab123 |
works on the very first instruction of the routine. To enable that
|
|
|
7ab123 |
test also on powerpc64le-linux, we can modify the code to call the
|
|
|
7ab123 |
test function via function pointer (which makes it use the global
|
|
|
7ab123 |
entry point in the ELFv2 ABI).
|
|
|
7ab123 |
|
|
|
7ab123 |
gdb/ChangeLog:
|
|
|
7ab123 |
|
|
|
7ab123 |
* gdbarch.sh (skip_entrypoint): New callback.
|
|
|
7ab123 |
* gdbarch.c, gdbarch.h: Regenerate.
|
|
|
7ab123 |
* symtab.c (skip_prologue_sal): Call gdbarch_skip_entrypoint.
|
|
|
7ab123 |
* infrun.c (fill_in_stop_func): Likewise.
|
|
|
7ab123 |
* ppc-linux-tdep.c: Include "elf/ppc64.h".
|
|
|
7ab123 |
(ppc_elfv2_elf_make_msymbol_special): New function.
|
|
|
7ab123 |
(ppc_elfv2_skip_entrypoint): Likewise.
|
|
|
7ab123 |
(ppc_linux_init_abi): Install them for ELFv2.
|
|
|
7ab123 |
|
|
|
7ab123 |
gdb/testsuite/ChangeLog:
|
|
|
7ab123 |
|
|
|
7ab123 |
* gdb.base/sigbpt.exp: Do not use "*" when setting breakpoint
|
|
|
7ab123 |
on a function.
|
|
|
7ab123 |
* gdb.base/step-bt.c: Call hello via function pointer to make
|
|
|
7ab123 |
sure its first instruction is executed on powerpc64le-linux.
|
|
|
7ab123 |
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/gdbarch.c
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/gdbarch.c
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/gdbarch.c
|
|
|
7ab123 |
@@ -200,6 +200,7 @@ struct gdbarch
|
|
|
7ab123 |
gdbarch_return_in_first_hidden_param_p_ftype *return_in_first_hidden_param_p;
|
|
|
7ab123 |
gdbarch_skip_prologue_ftype *skip_prologue;
|
|
|
7ab123 |
gdbarch_skip_main_prologue_ftype *skip_main_prologue;
|
|
|
7ab123 |
+ gdbarch_skip_entrypoint_ftype *skip_entrypoint;
|
|
|
7ab123 |
gdbarch_inner_than_ftype *inner_than;
|
|
|
7ab123 |
gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc;
|
|
|
7ab123 |
gdbarch_remote_breakpoint_from_pc_ftype *remote_breakpoint_from_pc;
|
|
|
7ab123 |
@@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch =
|
|
|
7ab123 |
default_return_in_first_hidden_param_p, /* return_in_first_hidden_param_p */
|
|
|
7ab123 |
0, /* skip_prologue */
|
|
|
7ab123 |
0, /* skip_main_prologue */
|
|
|
7ab123 |
+ 0, /* skip_entrypoint */
|
|
|
7ab123 |
0, /* inner_than */
|
|
|
7ab123 |
0, /* breakpoint_from_pc */
|
|
|
7ab123 |
default_remote_breakpoint_from_pc, /* remote_breakpoint_from_pc */
|
|
|
7ab123 |
@@ -672,6 +674,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
|
|
7ab123 |
if (gdbarch->skip_prologue == 0)
|
|
|
7ab123 |
fprintf_unfiltered (log, "\n\tskip_prologue");
|
|
|
7ab123 |
/* Skip verify of skip_main_prologue, has predicate. */
|
|
|
7ab123 |
+ /* Skip verify of skip_entrypoint, has predicate. */
|
|
|
7ab123 |
if (gdbarch->inner_than == 0)
|
|
|
7ab123 |
fprintf_unfiltered (log, "\n\tinner_than");
|
|
|
7ab123 |
if (gdbarch->breakpoint_from_pc == 0)
|
|
|
7ab123 |
@@ -1285,6 +1288,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
|
|
|
7ab123 |
"gdbarch_dump: single_step_through_delay = <%s>\n",
|
|
|
7ab123 |
host_address_to_string (gdbarch->single_step_through_delay));
|
|
|
7ab123 |
fprintf_unfiltered (file,
|
|
|
7ab123 |
+ "gdbarch_dump: gdbarch_skip_entrypoint_p() = %d\n",
|
|
|
7ab123 |
+ gdbarch_skip_entrypoint_p (gdbarch));
|
|
|
7ab123 |
+ fprintf_unfiltered (file,
|
|
|
7ab123 |
+ "gdbarch_dump: skip_entrypoint = <%s>\n",
|
|
|
7ab123 |
+ host_address_to_string (gdbarch->skip_entrypoint));
|
|
|
7ab123 |
+ fprintf_unfiltered (file,
|
|
|
7ab123 |
"gdbarch_dump: gdbarch_skip_main_prologue_p() = %d\n",
|
|
|
7ab123 |
gdbarch_skip_main_prologue_p (gdbarch));
|
|
|
7ab123 |
fprintf_unfiltered (file,
|
|
|
7ab123 |
@@ -2635,6 +2644,30 @@ set_gdbarch_skip_main_prologue (struct g
|
|
|
7ab123 |
}
|
|
|
7ab123 |
|
|
|
7ab123 |
int
|
|
|
7ab123 |
+gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch)
|
|
|
7ab123 |
+{
|
|
|
7ab123 |
+ gdb_assert (gdbarch != NULL);
|
|
|
7ab123 |
+ return gdbarch->skip_entrypoint != NULL;
|
|
|
7ab123 |
+}
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+CORE_ADDR
|
|
|
7ab123 |
+gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip)
|
|
|
7ab123 |
+{
|
|
|
7ab123 |
+ gdb_assert (gdbarch != NULL);
|
|
|
7ab123 |
+ gdb_assert (gdbarch->skip_entrypoint != NULL);
|
|
|
7ab123 |
+ if (gdbarch_debug >= 2)
|
|
|
7ab123 |
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_entrypoint called\n");
|
|
|
7ab123 |
+ return gdbarch->skip_entrypoint (gdbarch, ip);
|
|
|
7ab123 |
+}
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+void
|
|
|
7ab123 |
+set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch,
|
|
|
7ab123 |
+ gdbarch_skip_entrypoint_ftype skip_entrypoint)
|
|
|
7ab123 |
+{
|
|
|
7ab123 |
+ gdbarch->skip_entrypoint = skip_entrypoint;
|
|
|
7ab123 |
+}
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+int
|
|
|
7ab123 |
gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs)
|
|
|
7ab123 |
{
|
|
|
7ab123 |
gdb_assert (gdbarch != NULL);
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/gdbarch.h
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/gdbarch.h
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/gdbarch.h
|
|
|
7ab123 |
@@ -487,6 +487,24 @@ typedef CORE_ADDR (gdbarch_skip_main_pro
|
|
|
7ab123 |
extern CORE_ADDR gdbarch_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR ip);
|
|
|
7ab123 |
extern void set_gdbarch_skip_main_prologue (struct gdbarch *gdbarch, gdbarch_skip_main_prologue_ftype *skip_main_prologue);
|
|
|
7ab123 |
|
|
|
7ab123 |
+/* On some platforms, a single function may provide multiple entry points,
|
|
|
7ab123 |
+ e.g. one that is used for function-pointer calls and a different one
|
|
|
7ab123 |
+ that is used for direct function calls.
|
|
|
7ab123 |
+ In order to ensure that breakpoints set on the function will trigger
|
|
|
7ab123 |
+ no matter via which entry point the function is entered, a platform
|
|
|
7ab123 |
+ may provide the skip_entrypoint callback. It is called with IP set
|
|
|
7ab123 |
+ to the main entry point of a function (as determined by the symbol table),
|
|
|
7ab123 |
+ and should return the address of the innermost entry point, where the
|
|
|
7ab123 |
+ actual breakpoint needs to be set. Note that skip_entrypoint is used
|
|
|
7ab123 |
+ by GDB common code even when debugging optimized code, where skip_prologue
|
|
|
7ab123 |
+ is not used. */
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+extern int gdbarch_skip_entrypoint_p (struct gdbarch *gdbarch);
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+typedef CORE_ADDR (gdbarch_skip_entrypoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip);
|
|
|
7ab123 |
+extern CORE_ADDR gdbarch_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR ip);
|
|
|
7ab123 |
+extern void set_gdbarch_skip_entrypoint (struct gdbarch *gdbarch, gdbarch_skip_entrypoint_ftype *skip_entrypoint);
|
|
|
7ab123 |
+
|
|
|
7ab123 |
typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs);
|
|
|
7ab123 |
extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs);
|
|
|
7ab123 |
extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than);
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/gdbarch.sh
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/gdbarch.sh
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/gdbarch.sh
|
|
|
7ab123 |
@@ -527,6 +527,19 @@ m:int:return_in_first_hidden_param_p:str
|
|
|
7ab123 |
|
|
|
7ab123 |
m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0
|
|
|
7ab123 |
M:CORE_ADDR:skip_main_prologue:CORE_ADDR ip:ip
|
|
|
7ab123 |
+# On some platforms, a single function may provide multiple entry points,
|
|
|
7ab123 |
+# e.g. one that is used for function-pointer calls and a different one
|
|
|
7ab123 |
+# that is used for direct function calls.
|
|
|
7ab123 |
+# In order to ensure that breakpoints set on the function will trigger
|
|
|
7ab123 |
+# no matter via which entry point the function is entered, a platform
|
|
|
7ab123 |
+# may provide the skip_entrypoint callback. It is called with IP set
|
|
|
7ab123 |
+# to the main entry point of a function (as determined by the symbol table),
|
|
|
7ab123 |
+# and should return the address of the innermost entry point, where the
|
|
|
7ab123 |
+# actual breakpoint needs to be set. Note that skip_entrypoint is used
|
|
|
7ab123 |
+# by GDB common code even when debugging optimized code, where skip_prologue
|
|
|
7ab123 |
+# is not used.
|
|
|
7ab123 |
+M:CORE_ADDR:skip_entrypoint:CORE_ADDR ip:ip
|
|
|
7ab123 |
+
|
|
|
7ab123 |
f:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0
|
|
|
7ab123 |
m:const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0:
|
|
|
7ab123 |
# Return the adjusted address and kind to use for Z0/Z1 packets.
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/infrun.c
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/infrun.c
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/infrun.c
|
|
|
7ab123 |
@@ -3162,6 +3162,10 @@ fill_in_stop_func (struct gdbarch *gdbar
|
|
|
7ab123 |
ecs->stop_func_start
|
|
|
7ab123 |
+= gdbarch_deprecated_function_start_offset (gdbarch);
|
|
|
7ab123 |
|
|
|
7ab123 |
+ if (gdbarch_skip_entrypoint_p (gdbarch))
|
|
|
7ab123 |
+ ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch,
|
|
|
7ab123 |
+ ecs->stop_func_start);
|
|
|
7ab123 |
+
|
|
|
7ab123 |
ecs->stop_func_filled_in = 1;
|
|
|
7ab123 |
}
|
|
|
7ab123 |
}
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/ppc-linux-tdep.c
|
|
|
7ab123 |
@@ -44,6 +44,7 @@
|
|
|
7ab123 |
#include "observer.h"
|
|
|
7ab123 |
#include "auxv.h"
|
|
|
7ab123 |
#include "elf/common.h"
|
|
|
7ab123 |
+#include "elf/ppc64.h"
|
|
|
7ab123 |
#include "exceptions.h"
|
|
|
7ab123 |
#include "arch-utils.h"
|
|
|
7ab123 |
#include "spu-tdep.h"
|
|
|
7ab123 |
@@ -875,6 +876,55 @@ ppc_linux_core_read_description (struct
|
|
|
7ab123 |
}
|
|
|
7ab123 |
}
|
|
|
7ab123 |
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+/* Implementation of `gdbarch_elf_make_msymbol_special', as defined in
|
|
|
7ab123 |
+ gdbarch.h. This implementation is used for the ELFv2 ABI only. */
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+static void
|
|
|
7ab123 |
+ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
|
|
|
7ab123 |
+{
|
|
|
7ab123 |
+ elf_symbol_type *elf_sym = (elf_symbol_type *)sym;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ /* If the symbol is marked as having a local entry point, set a target
|
|
|
7ab123 |
+ flag in the msymbol. We currently only support local entry point
|
|
|
7ab123 |
+ offsets of 8 bytes, which is the only entry point offset ever used
|
|
|
7ab123 |
+ by current compilers. If/when other offsets are ever used, we will
|
|
|
7ab123 |
+ have to use additional target flag bits to store them. */
|
|
|
7ab123 |
+ switch (PPC64_LOCAL_ENTRY_OFFSET (elf_sym->internal_elf_sym.st_other))
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ default:
|
|
|
7ab123 |
+ break;
|
|
|
7ab123 |
+ case 8:
|
|
|
7ab123 |
+ MSYMBOL_TARGET_FLAG_1 (msym) = 1;
|
|
|
7ab123 |
+ break;
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+}
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+/* Implementation of `gdbarch_skip_entrypoint', as defined in
|
|
|
7ab123 |
+ gdbarch.h. This implementation is used for the ELFv2 ABI only. */
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+static CORE_ADDR
|
|
|
7ab123 |
+ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc)
|
|
|
7ab123 |
+{
|
|
|
7ab123 |
+ struct minimal_symbol *fun;
|
|
|
7ab123 |
+ int local_entry_offset = 0;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ fun = lookup_minimal_symbol_by_pc (pc);
|
|
|
7ab123 |
+ if (fun == NULL)
|
|
|
7ab123 |
+ return pc;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ /* See ppc_elfv2_elf_make_msymbol_special for how local entry point
|
|
|
7ab123 |
+ offset values are encoded. */
|
|
|
7ab123 |
+ if (MSYMBOL_TARGET_FLAG_1 (fun))
|
|
|
7ab123 |
+ local_entry_offset = 8;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ if (SYMBOL_VALUE_ADDRESS (fun) <= pc
|
|
|
7ab123 |
+ && pc < SYMBOL_VALUE_ADDRESS (fun) + local_entry_offset)
|
|
|
7ab123 |
+ return SYMBOL_VALUE_ADDRESS (fun) + local_entry_offset;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ return pc;
|
|
|
7ab123 |
+}
|
|
|
7ab123 |
+
|
|
|
7ab123 |
/* Implementation of `gdbarch_stap_is_single_operand', as defined in
|
|
|
7ab123 |
gdbarch.h. */
|
|
|
7ab123 |
|
|
|
7ab123 |
@@ -1341,6 +1391,13 @@ ppc_linux_init_abi (struct gdbarch_info
|
|
|
7ab123 |
set_gdbarch_elf_make_msymbol_special
|
|
|
7ab123 |
(gdbarch, ppc64_elf_make_msymbol_special);
|
|
|
7ab123 |
}
|
|
|
7ab123 |
+ else
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ set_gdbarch_elf_make_msymbol_special
|
|
|
7ab123 |
+ (gdbarch, ppc_elfv2_elf_make_msymbol_special);
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ set_gdbarch_skip_entrypoint (gdbarch, ppc_elfv2_skip_entrypoint);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
|
|
|
7ab123 |
/* Shared library handling. */
|
|
|
7ab123 |
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/symtab.c
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/symtab.c
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/symtab.c
|
|
|
7ab123 |
@@ -2872,6 +2872,8 @@ skip_prologue_sal (struct symtab_and_lin
|
|
|
7ab123 |
|
|
|
7ab123 |
/* Skip "first line" of function (which is actually its prologue). */
|
|
|
7ab123 |
pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
|
|
7ab123 |
+ if (gdbarch_skip_entrypoint_p (gdbarch))
|
|
|
7ab123 |
+ pc = gdbarch_skip_entrypoint (gdbarch, pc);
|
|
|
7ab123 |
if (skip)
|
|
|
7ab123 |
pc = gdbarch_skip_prologue (gdbarch, pc);
|
|
|
7ab123 |
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/testsuite/gdb.base/sigbpt.exp
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/testsuite/gdb.base/sigbpt.exp
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/testsuite/gdb.base/sigbpt.exp
|
|
|
7ab123 |
@@ -82,7 +82,7 @@ gdb_test "break keeper"
|
|
|
7ab123 |
set bowler_addrs bowler
|
|
|
7ab123 |
set segv_addr none
|
|
|
7ab123 |
gdb_test {display/i $pc}
|
|
|
7ab123 |
-gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
|
|
|
7ab123 |
+gdb_test "advance bowler" "bowler.*" "advance to the bowler"
|
|
|
7ab123 |
set test "stepping to fault"
|
|
|
7ab123 |
set signame "SIGSEGV"
|
|
|
7ab123 |
gdb_test_multiple "stepi" "$test" {
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/testsuite/gdb.base/step-bt.c
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/testsuite/gdb.base/step-bt.c
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/testsuite/gdb.base/step-bt.c
|
|
|
7ab123 |
@@ -23,10 +23,19 @@ hello (void)
|
|
|
7ab123 |
printf ("Hello world.\n");
|
|
|
7ab123 |
}
|
|
|
7ab123 |
|
|
|
7ab123 |
+/* The test case uses "break *hello" to make sure to step at the very
|
|
|
7ab123 |
+ first instruction of the function. This causes a problem running
|
|
|
7ab123 |
+ the test on powerpc64le-linux, since the first instruction belongs
|
|
|
7ab123 |
+ to the global entry point prologue, which is skipped when doing a
|
|
|
7ab123 |
+ local direct function call. To make sure that first instruction is
|
|
|
7ab123 |
+ indeed being executed and the breakpoint hits, we make sure to call
|
|
|
7ab123 |
+ the routine via an indirect call. */
|
|
|
7ab123 |
+void (*ptr) (void) = hello;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
int
|
|
|
7ab123 |
main (void)
|
|
|
7ab123 |
{
|
|
|
7ab123 |
- hello ();
|
|
|
7ab123 |
+ ptr ();
|
|
|
7ab123 |
|
|
|
7ab123 |
return 0;
|
|
|
7ab123 |
}
|