From patchwork Fri Mar 4 16:38:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 337 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:41:49 -0000 Delivered-To: patches@linaro.org Received: by 10.224.60.68 with SMTP id o4cs20800qah; Fri, 4 Mar 2011 08:38:07 -0800 (PST) Received: by 10.14.125.7 with SMTP id y7mr569958eeh.28.1299256686869; Fri, 04 Mar 2011 08:38:06 -0800 (PST) Received: from mtagate7.uk.ibm.com (mtagate7.uk.ibm.com [194.196.100.167]) by mx.google.com with ESMTPS id u19si5383176eeh.6.2011.03.04.08.38.06 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 04 Mar 2011 08:38:06 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning uweigand@de.ibm.com does not designate 194.196.100.167 as permitted sender) client-ip=194.196.100.167; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning uweigand@de.ibm.com does not designate 194.196.100.167 as permitted sender) smtp.mail=uweigand@de.ibm.com Received: from d06nrmr1307.portsmouth.uk.ibm.com (d06nrmr1307.portsmouth.uk.ibm.com [9.149.38.129]) by mtagate7.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p24Gc6Rx030068 for ; Fri, 4 Mar 2011 16:38:06 GMT Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1307.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p24GcIK91859742 for ; Fri, 4 Mar 2011 16:38:18 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p24Gc5C5004255 for ; Fri, 4 Mar 2011 09:38:05 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p24Gc4Uu004246 for ; Fri, 4 Mar 2011 09:38:04 -0700 Message-Id: <201103041638.p24Gc4Uu004246@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Fri, 04 Mar 2011 17:38:04 +0100 Subject: [rfa v2] Detect __aeabi_read_tp even without symbols To: patches@linaro.org Date: Fri, 4 Mar 2011 17:38:04 +0100 (CET) From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 http://sourceware.org/ml/gdb-patches/2010-12/msg00002.html ChangeLog: * 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. Index: gdb/arm-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.313 diff -u -p -r1.313 arm-tdep.c --- gdb/arm-tdep.c 18 Nov 2010 16:38:20 -0000 1.313 +++ gdb/arm-tdep.c 1 Dec 2010 13:52:02 -0000 @@ -449,39 +449,55 @@ arm_smash_text_address (struct gdbarch * } /* 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; - - 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; - - /* 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; + if (msym != NULL + && SYMBOL_VALUE_ADDRESS (msym) == pc + && SYMBOL_LINKAGE_NAME (msym) != NULL) + { + const char *name = SYMBOL_LINKAGE_NAME (msym); + + /* 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; - /* 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; + /* 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). */ + + 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; } @@ -825,7 +841,8 @@ thumb_analyze_prologue (struct 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; } @@ -1602,7 +1619,7 @@ arm_analyze_prologue (struct gdbarch *gd the stack. */ CORE_ADDR dest = BranchDest (current_pc, insn); - if (skip_prologue_function (dest)) + if (skip_prologue_function (gdbarch, dest, 0)) continue; else break;