From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8417 invoked by alias); 14 May 2008 23:03:14 -0000 Received: (qmail 8407 invoked by uid 22791); 14 May 2008 23:03:13 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate4.de.ibm.com (HELO mtagate4.de.ibm.com) (195.212.29.153) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 14 May 2008 23:02:52 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate4.de.ibm.com (8.13.8/8.13.8) with ESMTP id m4EN2nZF183800 for ; Wed, 14 May 2008 23:02:49 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m4EN2nPP2977856 for ; Thu, 15 May 2008 01:02:49 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m4EN2nPe030356 for ; Thu, 15 May 2008 01:02:49 +0200 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id m4EN2nHg030353 for ; Thu, 15 May 2008 01:02:49 +0200 Message-Id: <200805142302.m4EN2nHg030353@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Thu, 15 May 2008 01:02:49 +0200 Subject: [rfc] Fix problem with (maybe) non-relocated .opd section on powerpc64-linux To: gdb-patches@sourceware.org Date: Thu, 15 May 2008 12:08:00 -0000 From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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: 2008-05/txt/msg00455.txt.bz2 Hello, I've been running into problems when using the new_objfile observer to set a breakpoint on a newly loaded library on powerpc64-linux. The observer gets called when ld.so hits the _dl_debug_state breakpoint. At this point, my code was retrieving a symbol from the new library and setting a breakpoint. As this is powerpc64-linux, this involves resolving function descriptors, i.e. reading the target address from the .opd section. Now the current ppc64_linux_convert_from_func_ptr_addr simply reads the .opd contents from target memory. However, there may in fact be relocations that need to be applied to .opd. Usually, this is not a problem, because the _dl_debug_state breakpoint is hit only after ld.so has applied those relocations to target memory. However, this is not the case if the library is loaded via dlopen. In this case, the _dl_debug_state breakpoint is hit *before* relocations are applied. (I guess this might be considered a bug in glibc. But we have to live with existing glibc's in the field anyway ...) This is somewhat unfortunate, as I now cannot even manually apply the relocation (because it might already have been applied, and I cannot find out whether or not this has actually happened). So to solve this I'm now completely ignoring contents of .opd in target memory, and instead always retrieve the contents from the BFD. Those will certainly be non-relocated, so applying the relocation offset by hand will always result in the correct target address. Is this a reasonable thing to do? Tested on powerpc64-linux. Bye, Ulrich ChangeLog: * ppc-linux-tdep.c (ppc64_linux_convert_from_func_ptr_addr): Read and manually relocate .opd contents from BFD instead of reading them from target memory. diff -urNp gdb-orig/gdb/ppc-linux-tdep.c gdb-head/gdb/ppc-linux-tdep.c --- gdb-orig/gdb/ppc-linux-tdep.c 2008-05-14 20:28:48.244451000 +0200 +++ gdb-head/gdb/ppc-linux-tdep.c 2008-05-14 21:11:35.672042314 +0200 @@ -591,7 +591,31 @@ ppc64_linux_convert_from_func_ptr_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); + { + /* There may be relocations that need to be applied to the .opd + section. Unfortunately, this function may be called at a time + where these relocations have not yet been performed -- this can + happen for example shortly after a library has been loaded with + dlopen, but ld.so has not yet applied the relocations. + + To cope with both the case where the relocation has been applied, + and the case where it has not yet been applied, we do *not* read + the (maybe) relocated value from target memory, but we instead + read the non-relocated value from the BFD, and apply the relocation + offset manually. + + This makes the assumption that all .opd entries are always relocated + by the same offset the section itself was relocated. */ + + gdb_byte buf[8]; + int res; + + res = bfd_get_section_contents (s->bfd, s->the_bfd_section, + &buf, addr - s->addr, 8); + if (res != 0) + return extract_unsigned_integer (buf, 8) + - bfd_section_vma (s->bfd, s->the_bfd_section) + s->addr; + } return addr; } -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com