From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27459 invoked by alias); 24 Apr 2002 15:27:35 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 27437 invoked from network); 24 Apr 2002 15:27:32 -0000 Received: from unknown (HELO pizda.ninka.net) (216.101.162.242) by sources.redhat.com with SMTP; 24 Apr 2002 15:27:32 -0000 Received: from localhost (IDENT:davem@localhost.localdomain [127.0.0.1]) by pizda.ninka.net (8.9.3/8.9.3) with ESMTP id IAA30824; Wed, 24 Apr 2002 08:18:05 -0700 Date: Wed, 24 Apr 2002 08:27:00 -0000 Message-Id: <20020424.081805.94577950.davem@redhat.com> To: msnyder@redhat.com Cc: gdb@sources.redhat.com, gdb-patches@sources.redhat.com Subject: [RFA] Add glibc-tdep (was Re: [RFC] Time for a shared linux-nat.c module?) From: "David S. Miller" In-Reply-To: <20020423.215351.41174202.davem@redhat.com> References: <3CC5C242.D975892F@redhat.com> <20020423.215351.41174202.davem@redhat.com> Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-04/txt/msg00940.txt.bz2 From: "David S. Miller" Date: Tue, 23 Apr 2002 21:53:51 -0700 (PDT) From: Michael Snyder Date: Tue, 23 Apr 2002 13:21:22 -0700 I'm wondering if it isn't time to create a linux-nat.c module, shared by all host architectures, into which we can move some of this code instead of maintaining separate, duplicate versions. The code won't be even Linux specific, I think. For example the dynamic linker checks are glibc specific. The commentary refers to it as the "Hurd" resolver, but in fact it is more of a glibc thing than anything else. To this end I've implemented the following patch, and tested builds of arm-linux and i386-linux targets. Any objections? 2002-04-24 David S. Miller * glibc-tdep.c, glibc-tdep.h: New files. * config/arm/linux.mt (TDEPFILES): Add glibc-tdep.o * config/i386/linux.mt (TDEPFILES): Likewise. * i386-linux-tdep.c (glibc-tdep.h): Include. (find_minsym_and_objfile, skip_hurd_resolver): Delete. (i386_linux_skip_solib_resolver): Call glibc_skip_solib_resolver. * arm-linux-tdep.c (glibc-tdep.h): Include. (find_minsym_and_objfile, skip_hurd_resolver): Delete. (arm_linux_skip_solib_resolver): Call glibc_skip_solib_resolver. * Makefile.in (ALLDEPFILES): Add glibc-tdep.c (glibc-tdep.o): Add dependencies. (arm-linux-tdep.o): Update dependencies. (i386-linux-tdep.o): Likewise. --- ./config/arm/linux.mt.~1~ Wed Feb 13 21:48:32 2002 +++ ./config/arm/linux.mt Tue Apr 23 23:57:25 2002 @@ -1,5 +1,5 @@ # Target: ARM based machine running GNU/Linux TM_FILE= tm-linux.h -TDEPFILES= arm-tdep.o arm-linux-tdep.o solib.o solib-svr4.o solib-legacy.o +TDEPFILES= arm-tdep.o arm-linux-tdep.o glibc-tdep.o solib.o solib-svr4.o solib-legacy.o GDBSERVER_DEPFILES = linux-low.o linux-arm-low.o reg-arm.o --- ./config/i386/linux.mt.~1~ Wed Feb 13 21:48:33 2002 +++ ./config/i386/linux.mt Tue Apr 23 23:57:16 2002 @@ -1,5 +1,5 @@ # Target: Intel 386 running GNU/Linux -TDEPFILES= i386-tdep.o i386-linux-tdep.o i387-tdep.o \ +TDEPFILES= i386-tdep.o i386-linux-tdep.o glibc-tdep.o i387-tdep.o \ solib.o solib-svr4.o solib-legacy.o TM_FILE= tm-linux.h --- ./glibc-tdep.h.~1~ Wed Apr 24 08:20:15 2002 +++ ./glibc-tdep.h Tue Apr 23 23:54:45 2002 @@ -0,0 +1,22 @@ +/* Target dependent code for GDB on systems using GLIBC. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +CORE_ADDR +glibc_skip_solib_resolver (CORE_ADDR); --- ./glibc-tdep.c.~1~ Wed Apr 24 08:20:16 2002 +++ ./glibc-tdep.c Wed Apr 24 08:02:28 2002 @@ -0,0 +1,116 @@ +/* GLIBC target support. + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "frame.h" + +/* For glibc_skip_solib_resolver. */ +#include "symtab.h" +#include "symfile.h" +#include "objfiles.h" + +#include "glibc-tdep.h" + +/* Calling functions in shared libraries. */ + +/* Find the minimal symbol named NAME, and return both the minsym + struct and its objfile. This probably ought to be in minsym.c, but + everything there is trying to deal with things like C++ and + SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may + be considered too special-purpose for general consumption. */ + +static struct minimal_symbol * +find_minsym_and_objfile (char *name, struct objfile **objfile_p) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + if (SYMBOL_NAME (msym) + && STREQ (SYMBOL_NAME (msym), name)) + { + *objfile_p = objfile; + return msym; + } + } + } + + return 0; +} + +static CORE_ADDR +skip_hurd_resolver (CORE_ADDR pc) +{ + /* The HURD dynamic linker is part of the GNU C library, so many + GNU/Linux distributions use it. (All ELF versions, as far as I + know.) An unresolved PLT entry points to "_dl_runtime_resolve", + which calls "fixup" to patch the PLT, and then passes control to + the function. + + We look for the symbol `_dl_runtime_resolve', and find `fixup' in + the same objfile. If we are at the entry point of `fixup', then + we set a breakpoint at the return address (at the top of the + stack), and continue. + + It's kind of gross to do all these checks every time we're + called, since they don't change once the executable has gotten + started. But this is only a temporary hack --- upcoming versions + of GNU/Linux will provide a portable, efficient interface for + debugging programs that use shared libraries. */ + + struct objfile *objfile; + struct minimal_symbol *resolver + = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile); + + if (resolver) + { + struct minimal_symbol *fixup + = lookup_minimal_symbol ("fixup", NULL, objfile); + + if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) + return (SAVED_PC_AFTER_CALL (get_current_frame ())); + } + + return 0; +} + +/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c. + This function: + 1) decides whether a PLT has sent us into the linker to resolve + a function reference, and + 2) if so, tells us where to set a temporary breakpoint that will + trigger when the dynamic linker is done. */ + +CORE_ADDR +glibc_skip_solib_resolver (CORE_ADDR pc) +{ + CORE_ADDR result; + + /* Plug in functions for other kinds of resolvers here. */ + result = skip_hurd_resolver (pc); + if (result) + return result; + + return 0; +} --- ./i386-linux-tdep.c.~1~ Sun Feb 24 14:31:19 2002 +++ ./i386-linux-tdep.c Tue Apr 23 23:55:40 2002 @@ -33,6 +33,8 @@ #include "solib-svr4.h" /* For struct link_map_offsets. */ +#include "glibc-tdep.h" + /* Return the name of register REG. */ char * @@ -403,89 +405,10 @@ i386_linux_write_pc (CORE_ADDR pc, ptid_ /* Calling functions in shared libraries. */ -/* Find the minimal symbol named NAME, and return both the minsym - struct and its objfile. This probably ought to be in minsym.c, but - everything there is trying to deal with things like C++ and - SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may - be considered too special-purpose for general consumption. */ - -static struct minimal_symbol * -find_minsym_and_objfile (char *name, struct objfile **objfile_p) -{ - struct objfile *objfile; - - ALL_OBJFILES (objfile) - { - struct minimal_symbol *msym; - - ALL_OBJFILE_MSYMBOLS (objfile, msym) - { - if (SYMBOL_NAME (msym) - && STREQ (SYMBOL_NAME (msym), name)) - { - *objfile_p = objfile; - return msym; - } - } - } - - return 0; -} - -static CORE_ADDR -skip_hurd_resolver (CORE_ADDR pc) -{ - /* The HURD dynamic linker is part of the GNU C library, so many - GNU/Linux distributions use it. (All ELF versions, as far as I - know.) An unresolved PLT entry points to "_dl_runtime_resolve", - which calls "fixup" to patch the PLT, and then passes control to - the function. - - We look for the symbol `_dl_runtime_resolve', and find `fixup' in - the same objfile. If we are at the entry point of `fixup', then - we set a breakpoint at the return address (at the top of the - stack), and continue. - - It's kind of gross to do all these checks every time we're - called, since they don't change once the executable has gotten - started. But this is only a temporary hack --- upcoming versions - of GNU/Linux will provide a portable, efficient interface for - debugging programs that use shared libraries. */ - - struct objfile *objfile; - struct minimal_symbol *resolver - = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile); - - if (resolver) - { - struct minimal_symbol *fixup - = lookup_minimal_symbol ("fixup", NULL, objfile); - - if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) - return (SAVED_PC_AFTER_CALL (get_current_frame ())); - } - - return 0; -} - -/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c. - This function: - 1) decides whether a PLT has sent us into the linker to resolve - a function reference, and - 2) if so, tells us where to set a temporary breakpoint that will - trigger when the dynamic linker is done. */ - CORE_ADDR i386_linux_skip_solib_resolver (CORE_ADDR pc) { - CORE_ADDR result; - - /* Plug in functions for other kinds of resolvers here. */ - result = skip_hurd_resolver (pc); - if (result) - return result; - - return 0; + glibc_skip_solib_resolver (pc); } /* Fetch (and possibly build) an appropriate link_map_offsets --- ./arm-linux-tdep.c.~1~ Sat Feb 23 14:17:11 2002 +++ ./arm-linux-tdep.c Tue Apr 23 23:56:47 2002 @@ -29,6 +29,7 @@ #include "doublest.h" #include "arm-tdep.h" +#include "glibc-tdep.h" /* For shared library handling. */ #include "symtab.h" @@ -345,91 +346,10 @@ arm_linux_push_arguments (int nargs, str with. Before the fixup/resolver code returns, it actually calls the requested function and repairs &GOT[n+3]. */ -/* Find the minimal symbol named NAME, and return both the minsym - struct and its objfile. This probably ought to be in minsym.c, but - everything there is trying to deal with things like C++ and - SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may - be considered too special-purpose for general consumption. */ - -static struct minimal_symbol * -find_minsym_and_objfile (char *name, struct objfile **objfile_p) -{ - struct objfile *objfile; - - ALL_OBJFILES (objfile) - { - struct minimal_symbol *msym; - - ALL_OBJFILE_MSYMBOLS (objfile, msym) - { - if (SYMBOL_NAME (msym) - && strcmp (SYMBOL_NAME (msym), name) == 0) - { - *objfile_p = objfile; - return msym; - } - } - } - - return 0; -} - - -static CORE_ADDR -skip_hurd_resolver (CORE_ADDR pc) -{ - /* The HURD dynamic linker is part of the GNU C library, so many - GNU/Linux distributions use it. (All ELF versions, as far as I - know.) An unresolved PLT entry points to "_dl_runtime_resolve", - which calls "fixup" to patch the PLT, and then passes control to - the function. - - We look for the symbol `_dl_runtime_resolve', and find `fixup' in - the same objfile. If we are at the entry point of `fixup', then - we set a breakpoint at the return address (at the top of the - stack), and continue. - - It's kind of gross to do all these checks every time we're - called, since they don't change once the executable has gotten - started. But this is only a temporary hack --- upcoming versions - of GNU/Linux will provide a portable, efficient interface for - debugging programs that use shared libraries. */ - - struct objfile *objfile; - struct minimal_symbol *resolver - = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile); - - if (resolver) - { - struct minimal_symbol *fixup - = lookup_minimal_symbol ("fixup", NULL, objfile); - - if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) - return (SAVED_PC_AFTER_CALL (get_current_frame ())); - } - - return 0; -} - -/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c. - This function: - 1) decides whether a PLT has sent us into the linker to resolve - a function reference, and - 2) if so, tells us where to set a temporary breakpoint that will - trigger when the dynamic linker is done. */ - CORE_ADDR arm_linux_skip_solib_resolver (CORE_ADDR pc) { - CORE_ADDR result; - - /* Plug in functions for other kinds of resolvers here. */ - result = skip_hurd_resolver (pc); - - if (result) - return result; - - return 0; + return glibc_skip_solib_resolver (pc); } /* The constants below were determined by examining the following files --- ./Makefile.in.~1~ Mon Apr 22 17:53:30 2002 +++ ./Makefile.in Wed Apr 24 08:02:43 2002 @@ -1185,6 +1185,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 2 coff-solib.c \ core-sol2.c core-regset.c core-aout.c corelow.c \ dcache.c delta68-nat.c dpx2-nat.c dstread.c exec.c fork-child.c \ + glibc-tdep.c \ go32-nat.c h8300-tdep.c h8500-tdep.c \ hp300ux-nat.c hppa-tdep.c hppab-nat.c hppah-nat.c hpread.c \ i386-tdep.c i386b-nat.c i386mach-nat.c i386v-nat.c i386-linux-nat.c \ @@ -1263,7 +1264,8 @@ arm-linux-nat.o: arm-linux-nat.c $(defs_ $(gdb_string_h) $(regcache_h) arm-tdep.h arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \ - $(gdbtypes_h) $(floatformat_h) $(regcache_h) $(doublest_h) arm-tdep.h + $(gdbtypes_h) $(floatformat_h) $(regcache_h) $(doublest_h) arm-tdep.h \ + $(srcdir)/glibc-tdep.h arm-tdep.o: arm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(gdbcmd_h) \ $(gdbcore_h) $(gdb_string_h) $(dis_asm_h) $(regcache_h) $(doublest_h) \ @@ -1522,6 +1524,9 @@ gdbtk-wrapper.o: $(srcdir)/gdbtk/generic $(CC) -c $(INTERNAL_CFLAGS) $(IDE_CFLAGS) $(GDBTK_CFLAGS)\ $(srcdir)/gdbtk/generic/gdbtk-wrapper.c +glibc-tdep.o: glibc-tdep.c $(defs_h) $(frame_h) $(symtab_h) \ + $(symfile_h) $(objfiles_h) $(srcdir)/glibc-tdep.h + v850ice.o: v850ice.c $(defs_h) $(symtab_h) $(inferior_h) $(command_h) \ $(frame_h) $(breakpoint_h) $(gdbcore_h) $(value_h) $(symfile_h) \ $(gdb_string_h) $(target_h) $(objfiles_h) $(regcache_h) @@ -1618,7 +1623,7 @@ i386-linux-nat.o: i386-linux-nat.c $(def $(symtab_h) $(symfile_h) $(objfiles_h) $(regcache_h) i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \ - $(value_h) $(regcache_h) + $(value_h) $(regcache_h) $(srcdir)/glibc-tdep.h i386v4-nat.o: i386v4-nat.c $(defs_h) $(regcache_h)