* arm-tdep.c (skip_prologue_function): Add GDBARCH and IS_THUMB

arguments.  Skip in-prologue calls to glibc __aeabi_read_tp
	implementation even if no symbols are available.
	(thumb_analyze_prologue): Update call to skip_prologue_function.
	(arm_analyze_prologue): Likewise.
This commit is contained in:
Ulrich Weigand 2011-02-02 19:45:32 +00:00
parent 0e9e9abd6f
commit e0634ccfe8
2 changed files with 51 additions and 26 deletions

View File

@ -1,3 +1,11 @@
2011-02-02 Ulrich Weigand <ulrich.weigand@linaro.org>
* arm-tdep.c (skip_prologue_function): Add GDBARCH and IS_THUMB
arguments. Skip in-prologue calls to glibc __aeabi_read_tp
implementation even if no symbols are available.
(thumb_analyze_prologue): Update call to skip_prologue_function.
(arm_analyze_prologue): Likewise.
2011-02-02 Ulrich Weigand <ulrich.weigand@linaro.org>
* arm-tdep.c: Include "observer.h".

View File

@ -451,39 +451,55 @@ arm_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR val)
}
/* Return 1 if PC is the start of a compiler helper function which
can be safely ignored during prologue skipping. */
can be safely ignored during prologue skipping. IS_THUMB is true
if the function is known to be a Thumb function due to the way it
is being called. */
static int
skip_prologue_function (CORE_ADDR pc)
skip_prologue_function (struct gdbarch *gdbarch, CORE_ADDR pc, int is_thumb)
{
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
struct minimal_symbol *msym;
const char *name;
msym = lookup_minimal_symbol_by_pc (pc);
if (msym == NULL || SYMBOL_VALUE_ADDRESS (msym) != pc)
return 0;
if (msym != NULL
&& SYMBOL_VALUE_ADDRESS (msym) == pc
&& SYMBOL_LINKAGE_NAME (msym) != NULL)
{
const char *name = SYMBOL_LINKAGE_NAME (msym);
name = SYMBOL_LINKAGE_NAME (msym);
if (name == NULL)
return 0;
/* The GNU linker's Thumb call stub to foo is named
__foo_from_thumb. */
if (strstr (name, "_from_thumb") != NULL)
name += 2;
/* The GNU linker's Thumb call stub to foo is named
__foo_from_thumb. */
if (strstr (name, "_from_thumb") != NULL)
name += 2;
/* On soft-float targets, __truncdfsf2 is called to convert promoted
arguments to their argument types in non-prototyped
functions. */
if (strncmp (name, "__truncdfsf2", strlen ("__truncdfsf2")) == 0)
return 1;
if (strncmp (name, "__aeabi_d2f", strlen ("__aeabi_d2f")) == 0)
return 1;
/* On soft-float targets, __truncdfsf2 is called to convert promoted
arguments to their argument types in non-prototyped
functions. */
if (strncmp (name, "__truncdfsf2", strlen ("__truncdfsf2")) == 0)
return 1;
if (strncmp (name, "__aeabi_d2f", strlen ("__aeabi_d2f")) == 0)
return 1;
/* Internal functions related to thread-local storage. */
if (strncmp (name, "__tls_get_addr", strlen ("__tls_get_addr")) == 0)
return 1;
if (strncmp (name, "__aeabi_read_tp", strlen ("__aeabi_read_tp")) == 0)
return 1;
}
else
{
/* If we run against a stripped glibc, we may be unable to identify
special functions by name. Check for one important case,
__aeabi_read_tp, by comparing the *code* against the default
implementation (this is hand-written ARM assembler in glibc). */
/* Internal functions related to thread-local storage. */
if (strncmp (name, "__tls_get_addr", strlen ("__tls_get_addr")) == 0)
return 1;
if (strncmp (name, "__aeabi_read_tp", strlen ("__aeabi_read_tp")) == 0)
return 1;
if (!is_thumb
&& read_memory_unsigned_integer (pc, 4, byte_order_for_code)
== 0xe3e00a0f /* mov r0, #0xffff0fff */
&& read_memory_unsigned_integer (pc + 4, 4, byte_order_for_code)
== 0xe240f01f) /* sub pc, r0, #31 */
return 1;
}
return 0;
}
@ -842,7 +858,8 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
if (bit (inst2, 12) == 0)
nextpc = nextpc & 0xfffffffc;
if (!skip_prologue_function (nextpc))
if (!skip_prologue_function (gdbarch, nextpc,
bit (inst2, 12) != 0))
break;
}
@ -1814,7 +1831,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
the stack. */
CORE_ADDR dest = BranchDest (current_pc, insn);
if (skip_prologue_function (dest))
if (skip_prologue_function (gdbarch, dest, 0))
continue;
else
break;