From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9000 invoked by alias); 25 Apr 2004 06:07:55 -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 8992 invoked from network); 25 Apr 2004 06:07:53 -0000 Received: from unknown (HELO pippin.tausq.org) (64.81.244.94) by sources.redhat.com with SMTP; 25 Apr 2004 06:07:53 -0000 Received: by pippin.tausq.org (Postfix, from userid 1000) id CE35DCD299; Sat, 24 Apr 2004 23:08:15 -0700 (PDT) Date: Sun, 25 Apr 2004 06:07:00 -0000 From: Randolph Chung To: Joel Brobecker Cc: gdb-patches@sources.redhat.com Subject: Re: [patch/rfa] hppa-linux target, 2nd try Message-ID: <20040425060815.GK2923@tausq.org> Reply-To: Randolph Chung References: <20040424192614.GD2923@tausq.org> <20040425002520.GP2811@gnat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040425002520.GP2811@gnat.com> X-GPG: for GPG key, see http://www.tausq.org/gpg.txt User-Agent: Mutt/1.5.5.1+cvs20040105i X-SW-Source: 2004-04/txt/msg00607.txt.bz2 > I actually started looking at that about 10 days ago, but it is hard for > me to figure out what is going wrong, because I don't know too well the > machinery for calling functions inside shared libraries. And then I got > pre-empted by something else. > > It's something that's on my reasonably-near-future list. Something like this (derived from ia64) works for hppa-linux, but I have no idea how to do this for som. 2004-04-24 Randolph Chung * hppa-tdep.h (find_global_pointer): Add target-specific method to find a gp given a function address. (FIND_GLOBAL_POINTER): Convenience wrapper for find_global_pointer. * hppa-tdep.c (hppa32_push_dummy_call): Try to fill in the gp with the correct value when calling a function in a shared lib. * hppa-linux-tdep.c (generic_elf_find_global_pointer): New function. (hppa_linux_init_abi): Set find_global_pointer. Index: hppa-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/hppa-tdep.h,v retrieving revision 1.4 diff -u -p -r1.4 hppa-tdep.h --- hppa-tdep.h 23 Apr 2004 02:54:21 -0000 1.4 +++ hppa-tdep.h 25 Apr 2004 06:01:42 -0000 @@ -33,7 +33,12 @@ struct gdbarch_tdep /* Is this an ELF target? This can be 64-bit HP-UX, or a 32/64-bit GNU/Linux system. */ int is_elf; + + CORE_ADDR (*find_global_pointer) (CORE_ADDR); }; + +#define FIND_GLOBAL_POINTER \ + (gdbarch_tdep (current_gdbarch)->find_global_pointer) /* * Unwind table and descriptor. Index: hppa-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-tdep.c,v retrieving revision 1.151 diff -u -p -r1.151 hppa-tdep.c --- hppa-tdep.c 24 Apr 2004 06:13:32 -0000 1.151 +++ hppa-tdep.c 25 Apr 2004 06:01:37 -0000 @@ -856,7 +856,12 @@ hppa32_push_dummy_call (struct gdbarch * if (struct_return) write_register (28, struct_addr); + gp = FIND_GLOBAL_POINTER (func_addr); + + if (gp != 0) + write_register (19, gp); + /* Set the return address. */ regcache_cooked_write_unsigned (regcache, RP_REGNUM, bp_addr); /* Update the Stack Pointer. */ diff -u hppa-linux-tdep.c hppa-linux-tdep.c --- hppa-linux-tdep.c 2004-04-24 11:39:03.211793064 -0700 +++ hppa-linux-tdep.c 2004-04-24 20:28:40.486912952 -0700 @@ -30,6 +30,8 @@ #include "dwarf2-frame.h" #include "hppa-tdep.h" +#include "elf/common.h" + #if 0 /* Convert DWARF register number REG to the appropriate register number used by GDB. */ @@ -456,6 +458,71 @@ return NULL; } +/* Attempt to find (and return) the global pointer for the given + function. + + This is a rather nasty bit of code searchs for the .dynamic section + in the objfile corresponding to the pc of the function we're trying + to call. Once it finds the addresses at which the .dynamic section + lives in the child process, it scans the Elf32_Dyn entries for a + DT_PLTGOT tag. If it finds one of these, the corresponding + d_un.d_ptr value is the global pointer. */ + +static CORE_ADDR +generic_elf_find_global_pointer (CORE_ADDR faddr) +{ + struct obj_section *faddr_sect; + + faddr_sect = find_pc_section (faddr); + if (faddr_sect != NULL) + { + struct obj_section *osect; + + ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect) + { + if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0) + break; + } + + if (osect < faddr_sect->objfile->sections_end) + { + CORE_ADDR addr; + + addr = osect->addr; + while (addr < osect->endaddr) + { + int status; + LONGEST tag; + char buf[4]; + + status = target_read_memory (addr, buf, sizeof (buf)); + if (status != 0) + break; + tag = extract_signed_integer (buf, sizeof (buf)); + + if (tag == DT_PLTGOT) + { + CORE_ADDR global_pointer; + + status = target_read_memory (addr + 4, buf, sizeof (buf)); + if (status != 0) + break; + global_pointer = extract_unsigned_integer (buf, sizeof (buf)); + + /* The payoff... */ + return global_pointer; + } + + if (tag == DT_NULL) + break; + + addr += 8; + } + } + } + return 0; +} + /* Forward declarations. */ extern initialize_file_ftype _initialize_hppa_linux_tdep; @@ -467,6 +534,8 @@ /* Linux is always ELF. */ tdep->is_elf = 1; + tdep->find_global_pointer = generic_elf_find_global_pointer; + set_gdbarch_write_pc (gdbarch, hppa_linux_target_write_pc); frame_unwind_append_sniffer (gdbarch, hppa_linux_sigtramp_unwind_sniffer); -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/