From e0634ccfe8718b76b5e77c983a3cebfa7707747a Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Wed, 2 Feb 2011 19:45:32 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 8 ++++++ gdb/arm-tdep.c | 69 +++++++++++++++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2330886fc4..1c467ea938 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2011-02-02 Ulrich Weigand + + * 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 * arm-tdep.c: Include "observer.h". diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 5d2b6322a8..a9abf2d0a4 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -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; -- 2.34.1