From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8006 invoked by alias); 1 Mar 2007 20:06:09 -0000 Received: (qmail 7998 invoked by uid 22791); 1 Mar 2007 20:06:07 -0000 X-Spam-Check-By: sourceware.org Received: from igw3.br.ibm.com (HELO igw3.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 01 Mar 2007 20:05:55 +0000 Received: from mailhub3.br.ibm.com (unknown [9.18.232.110]) by igw3.br.ibm.com (Postfix) with ESMTP id 240F4390330 for ; Thu, 1 Mar 2007 17:01:14 -0300 (BRT) Received: from d24av02.br.ibm.com (d24av02.br.ibm.com [9.18.232.47]) by mailhub3.br.ibm.com (8.13.8/8.13.8/NCO v8.2) with ESMTP id l21K5bJb1597538 for ; Thu, 1 Mar 2007 17:05:37 -0300 Received: from d24av02.br.ibm.com (loopback [127.0.0.1]) by d24av02.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l21K4XuS016626 for ; Thu, 1 Mar 2007 17:04:33 -0300 Received: from [9.18.238.151] (kadinsky.br.ibm.com [9.18.238.151]) by d24av02.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l21K4XMG016623 for ; Thu, 1 Mar 2007 17:04:33 -0300 Subject: [PATCH 24700] From: Jose Flavio Aguilar Paulino To: gdb-patches@sourceware.org In-Reply-To: <20070301183700.GA19796@caradoc.them.org> References: <1172777198.10229.11.camel@kadinsky.prado> <20070301183700.GA19796@caradoc.them.org> Content-Type: multipart/mixed; boundary="=-RcXkoTCnNzQPkhPRj/4u" Date: Thu, 01 Mar 2007 20:06:00 -0000 Message-Id: <1172783136.10229.28.camel@kadinsky.prado> Mime-Version: 1.0 X-Mailer: Evolution 2.8.2 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-03/txt/msg00004.txt.bz2 --=-RcXkoTCnNzQPkhPRj/4u Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content-length: 3189 This patch modifies the file. It was noticed in GDB for PPC64 that the command "set var" failed when used to change a string value, the intent of this patch is to solve this gdb64's problem. I could not detect any regressions that could be caused by this patch in GDB's testsuite. The problem solved by this patch was noticied in SLES10. Thats the first time I submit a Patch, so sorry the errors. First I will give you a concrete example: -------------------------------------------------------- ~/bugz_24700> cat test.c #define _GNU_SOURCE #include #include static void fault_func (char *arg) { *arg = 'b'; } int main (int argc, char *argv[]) { int cnt = 0; char *ptr = NULL; printf("%s\n", "hello world"); fault_func (ptr); printf("%s\n", ptr) return 0; } ~/bugz_24700> gcc -m64 -g test.c ~/bugz_24700> gdb64 a.out GNU gdb 6.4 Copyright 2005 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "ppc64-suse-linux"...Using host libthread_db library "/lib64/power4/libthread_db.so.1". (gdb) start Breakpoint 1 at 0x10000604: file test.c, line 13. Starting program: /home/pgilliam/bugz_24700/a.out main (argc=1, argv=0xfffffb3f2b8) at test.c:13 13 int cnt = 0; (gdb) n 14 char *ptr = NULL; (gdb) n 16 printf("hello world\n"); (gdb) n hello world 18 fault_func (ptr); (gdb) set var ptr="foo" Program received signal SIGSEGV, Segmentation fault. 0x000000000001cba0 in ?? () The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on" Evaluation of the expression containing the function (at 0x1cba0) will be abando ned. (gdb) q -------------------------------------------------------- At the begining of the investigation, it looks like gdbarch_convert_from_func_ptr_addr is returning the wrong value, and it is, but it's not its fault! It calls ppc64_linux_convert_from_func_ptr_addr (correctly) which needs to know the section the address is in. So target_section_by_addr is called to get the section, but it returns null. GDB finds one malloc (from /lib64/ld64.so.1 presumably) and the program linked with another(presumably from libc) This is from the shipping gdb64 from SLES10. The problem was that 'ppc64_linux_convert_from_func_ptr_addr()' first wanted to make sure that the function pointer for 'malloc()' pointed into an .opd section before it was 'dereferenced' It used 'target_section_by_addr()' to do the search, and the section containing the PLT pointed to by the function pointer was not in the section table being searched. But there is another section table. The patch changes things so that if the search of the first section table fails, the second table is searched. -- José Flávio Aguilar Paulino Software Engineer LoP Toolchain Team IBM --=-RcXkoTCnNzQPkhPRj/4u Content-Disposition: attachment; filename=24700.patch Content-Type: text/x-patch; name=24700.patch; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-length: 2025 Index: ppc-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v retrieving revision 1.81 diff -a -u -r1.81 ppc-linux-tdep.c --- ppc-linux-tdep.c 9 Jan 2007 17:58:55 -0000 1.81 +++ ppc-linux-tdep.c 8 Feb 2007 01:11:15 -0000 @@ -753,11 +753,57 @@ CORE_ADDR addr, struct target_ops *targ) { + CORE_ADDR addr2deref = 0; struct section_table *s = target_section_by_addr (targ, addr); + char buf[sizeof (ULONGEST)]; + struct objfile *objfile; + struct obj_section *osect; + asection *sect; + CORE_ADDR sect_addr; /* Check if ADDR points to a function descriptor. */ - if (s && strcmp (s->the_bfd_section->name, ".opd") == 0) - return get_target_memory_unsigned (targ, addr, 8); + + + if (s) + { + if (strcmp (s->the_bfd_section->name, ".opd") != 0) + /* Found a the section, but it's not an .opd section. */ + return addr; + addr2deref = addr; + } + else + /* The followin table search has been copied from printcmd.c */ + ALL_OBJSECTIONS (objfile, osect) + { + /* Only process each object file once, even if there's a separate + debug file. */ + if (objfile->separate_debug_objfile_backlink) + continue; + + sect = osect->the_bfd_section; + sect_addr = overlay_mapped_address (addr, sect); + + if (osect->addr <= sect_addr && sect_addr < osect->endaddr) + { + if (strcmp (sect->name, ".opd") != 0) + /* Found the section, but it's not an .opd section. */ + return addr; + addr2deref = addr; + break; + } + } + + if (addr2deref) + { + if (targ != ¤t_target) + return get_target_memory_unsigned (targ, addr2deref, 8); + else + { + gdb_assert (8 <= sizeof (buf)); + target_read_memory(addr, buf, 8); + return extract_unsigned_integer (buf, 8); + } + } return addr; } --=-RcXkoTCnNzQPkhPRj/4u--