diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2011-02-02 19:45:32 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2011-02-02 19:45:32 +0000 |
commit | e0634ccfe8718b76b5e77c983a3cebfa7707747a (patch) | |
tree | 29c5d0380acccc38dc6640a5d444e6a1f1e9cc4d /gdb/arm-tdep.c | |
parent | 0e9e9abd6f3f095d118bb6e6f0c995638a120d3c (diff) | |
download | gdb-e0634ccfe8718b76b5e77c983a3cebfa7707747a.zip gdb-e0634ccfe8718b76b5e77c983a3cebfa7707747a.tar.gz gdb-e0634ccfe8718b76b5e77c983a3cebfa7707747a.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r-- | gdb/arm-tdep.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 5d2b632..a9abf2d 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; |