From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15790 invoked by alias); 26 Nov 2003 00:11:44 -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 15711 invoked from network); 26 Nov 2003 00:11:41 -0000 Received: from unknown (HELO palrel12.hp.com) (156.153.255.237) by sources.redhat.com with SMTP; 26 Nov 2003 00:11:41 -0000 Received: from hplms2.hpl.hp.com (hplms2.hpl.hp.com [15.0.152.33]) by palrel12.hp.com (Postfix) with ESMTP id DEF2D1C00A2A; Tue, 25 Nov 2003 16:11:40 -0800 (PST) Received: from napali.hpl.hp.com (napali.hpl.hp.com [15.4.89.123]) by hplms2.hpl.hp.com (8.12.10/8.12.10/HPL-PA Hub) with ESMTP id hAQ0Bdew010224; Tue, 25 Nov 2003 16:11:40 -0800 (PST) Received: from napali.hpl.hp.com (napali [127.0.0.1]) by napali.hpl.hp.com (8.12.3/8.12.3/Debian-6.6) with ESMTP id hAQ0BdFO007486; Tue, 25 Nov 2003 16:11:39 -0800 Received: (from davidm@localhost) by napali.hpl.hp.com (8.12.3/8.12.3/Debian-6.6) id hAQ0BdKh007482; Tue, 25 Nov 2003 16:11:39 -0800 From: David Mosberger MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16323.61371.6654.950171@napali.hpl.hp.com> Date: Wed, 26 Nov 2003 00:11:00 -0000 To: Andrew Cagney Cc: davidm@hpl.hp.com, Kevin Buettner , "J. Johnston" , gdb-patches@sources.redhat.com Subject: Re: RFA: ia64 portion of libunwind patch In-Reply-To: <3FB0149C.1060908@redhat.com> References: <3FA2B71A.3080905@redhat.com> <3FA2CA1B.7000502@redhat.com> <16290.59502.799536.383397@napali.hpl.hp.com> <3FAC12D3.2070207@redhat.com> <16300.8192.489647.740612@napali.hpl.hp.com> <3FAC2454.2030009@redhat.com> <16300.9949.513264.716812@napali.hpl.hp.com> <3FAC2D03.8070607@redhat.com> <16300.12503.585501.180768@napali.hpl.hp.com> <3FAC33B3.2030403@redhat.com> <1031108001337.ZM18506@localhost.localdomain> <3FAC388A.10207@redhat.com> <16300.39298.323956.667764@napali.hpl.hp.com> <3FAD7F01.2050407@gnu.org> <16304.3297.662733.250523@napali.hpl.hp.com> <3FB0149C.1060908@redhat.com> Reply-To: davidm@hpl.hp.com X-URL: http://www.hpl.hp.com/personal/David_Mosberger/ X-SW-Source: 2003-11/txt/msg00588.txt.bz2 Hi Andrew, >>>>> On Mon, 10 Nov 2003 17:43:40 -0500, Andrew Cagney said: >> In any case, perhaps it is possible to add incremental reading >> support by stealing a bit from one of the members in the >> "unw_dyn_table_info". All we really need is a single bit to >> indicate whether the table-data should be fetched from >> remote-memory. I'll think about it some more. Andrew> It would be appreciated. My suggestion was to use memory Andrew> reads when the unwind table pointer was NULL. However, Andrew> anything would help. OK, I looked into this a bit more: we can't just redefine the meaning of the unwind-table pointer, because it may have the wrong size when unwinding across platforms. For example, when cross-unwinding an ia64 application on an x86 host (happens regularly with the Ski simulator), the pointer will be 32 bits in size but the remote address will be 64 bits. The reverse problem can happen when registering unwind info, so there is no quick way out. Fortunately, it's still possible to have a clean solution: we can simply add a new unwind-table format, which is identical to the standard table format except that the table-data is a remote-address (i.e., "unw_word_t" instead of "unw_word_t *"). I checked in a patch to do just that in libunwind: http://unwind.bkbits.net:8080/libunwind/cset@1.123 If you don't want to deal with bitkeeper, libunwind v0.95 should be due out shortly and will include this change. I'm rather happy with this solution because it's clearly the clean way of doing it and it retains backwards compatibility. The one incompatibility introduced by this patch is that the interface of the _Uia64_find_dyn_list() helper-routine changed slightly. The only known user of that interface is gdb at the moment, so I think that's OK (and, in retrospect, the old interface was a mistake). Below, I attached a patch which updates gdb to use the remote-table facility. It doesn't try to retain backwards compatibility. If that were an issue, you could autoconf-check whether the enumeration symbol UNW_INFO_FORMAT_REMOTE_TABLE is defined by and use the old code if not. While I didn't try to run the gdb test-suite, I did try a test program which does some on-the-fly code-generation and the backtrace command seemed to work fine. For example: (gdb) bt #0 0x6000000000004022 in ?? () #1 0x60000000000040a0 in ?? () #2 0x6000000000004140 in ?? () #3 0x40000000000017e0 in main (argc=-19616, argv=0x6000000000004180) at ../../libunwind/tests/ia64-test-dyn1.c:196 Now if only gdb were able to call unw_get_proc_name() when it can't find a symbol-name. If it did that, the backtrace would even show the proper function names for the dynamically generatd code. Is this something that could be added? Another concern: at the moment, libunwind-frame.c dlopen()'s libunwind.so. This doesn't really work, because libunwind.so is just a convenience symlink which allows native apps to link against the proper libunwind with "-lunwind". The real library is called libunwind-$TARGET.so where $TARGET would be one of ia64, x86, or hppa, depending on the target architecture. For details, see the "Files" section of this URL: http://www.hpl.hp.com/research/linux/libunwind/man/libunwind(3).php Also, if multi-target support is to work, gdb would have to do a separate dlopen for each target architecture being debugged. Thanks, --david ChangeLog 2003-11-25 David Mosberger * libunwind-frame.c (unw_find_dyn_list_p): Replace most arguments with a single unw_dyn_info_t pointer. (libunwind_find_dyn_list): Likewise. * libunwind-frame.h: Likewise. * ia64-tdep.c (ia64_find_unwind_table): Switch to using UNW_INFO_FORMAT_REMOTE_TABLE so we can avoid having to read in the entire unwind-table at once. Support for this table format has been added to libunwind v0.95. (ia64_find_proc_info_x): Adjust for remote-unwind-table changes. (ia64_get_dyn_info_list): Adjust for interface change for libunwind_find_dyn_list(). Index: ia64-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/ia64-tdep.c,v retrieving revision 1.104 diff -u -r1.104 ia64-tdep.c --- ia64-tdep.c 17 Nov 2003 21:38:36 -0000 1.104 +++ ia64-tdep.c 25 Nov 2003 23:48:24 -0000 @@ -2452,23 +2452,11 @@ dip->start_ip = segbase; dip->end_ip = dip->start_ip + p_text->p_memsz; dip->gp = FIND_GLOBAL_POINTER (ip); - dip->format = UNW_INFO_FORMAT_TABLE; - dip->u.ti.name_ptr = (unw_word_t) bfd_get_filename (bfd); - dip->u.ti.segbase = segbase; - dip->u.ti.table_len = p_unwind->p_memsz / sizeof (unw_word_t); - - /* The following can happen in corner cases where dynamically - generated code falls into the same page that contains the - data-segment and the page-offset of the code is within the first - page of the executable. */ - if (ip < dip->start_ip || ip >= dip->end_ip) - return -UNW_ENOINFO; - - /* Read in the libunwind table. */ - *buf = xmalloc (p_unwind->p_memsz); - target_read_memory (p_unwind->p_vaddr + load_base, (char *)(*buf), p_unwind->p_memsz); - - dip->u.ti.table_data = (unw_word_t *)(*buf); + dip->format = UNW_INFO_FORMAT_REMOTE_TABLE; + dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd); + dip->u.rti.segbase = segbase; + dip->u.rti.table_len = p_unwind->p_memsz / sizeof (unw_word_t); + dip->u.rti.table_data = p_unwind->p_vaddr + load_base; return 0; } @@ -2490,22 +2478,32 @@ version. */ if (get_kernel_table (ip, &di) < 0) return -UNW_ENOINFO; + + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, "%s: %lx -> " + "(name=`%s',segbase=%lx,start=%lx,end=%lx,gp=%lx," + "length=%lu,data=%p)\n", __FUNCTION__, + ip, (char *)di.u.ti.name_ptr, + di.u.ti.segbase, di.start_ip, di.end_ip, + di.gp, di.u.ti.table_len, di.u.ti.table_data); } else { ret = ia64_find_unwind_table (sec->objfile, ip, &di, &buf); if (ret < 0) return ret; - } - if (gdbarch_debug >= 1) - fprintf_unfiltered (gdb_stdlog, "acquire_unwind_info: %lx -> " - "(name=`%s',segbase=%lx,start=%lx,end=%lx,gp=%lx," - "length=%lu,data=%p)\n", ip, (char *)di.u.ti.name_ptr, - di.u.ti.segbase, di.start_ip, di.end_ip, - di.gp, di.u.ti.table_len, di.u.ti.table_data); + if (gdbarch_debug >= 1) + fprintf_unfiltered (gdb_stdlog, "%s: %lx -> " + "(name=`%s',segbase=%lx,start=%lx,end=%lx,gp=%lx," + "length=%lu,data=%lx)\n", __FUNCTION__, + ip, (char *)di.u.rti.name_ptr, + di.u.rti.segbase, di.start_ip, di.end_ip, + di.gp, di.u.rti.table_len, di.u.rti.table_data); + } - ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info, arg); + ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info, + arg); /* We no longer need the dyn info storage so free it. */ xfree (buf); @@ -2545,10 +2543,7 @@ ret = ia64_find_unwind_table (objfile, ip, &di, &buf); if (ret >= 0) { - addr = libunwind_find_dyn_list (as, di.u.ti.table_data, - (di.u.ti.table_len - * sizeof (di.u.ti.table_data[0])), - di.u.ti.segbase, di.gp, arg); + addr = libunwind_find_dyn_list (as, &di, arg); /* We no longer need the dyn info storage so free it. */ xfree (buf); Index: libunwind-frame.c =================================================================== RCS file: /cvs/src/src/gdb/libunwind-frame.c,v retrieving revision 1.1 diff -u -r1.1 libunwind-frame.c --- libunwind-frame.c 14 Nov 2003 21:17:51 -0000 1.1 +++ libunwind-frame.c 25 Nov 2003 23:48:24 -0000 @@ -58,8 +58,8 @@ static unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int); static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *, unw_proc_info_t *, int, void *); -static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, void *, size_t, - unw_word_t, unw_word_t, void *); +static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *, + void *); struct libunwind_frame_cache @@ -170,11 +170,10 @@ return cache; } -unw_word_t -libunwind_find_dyn_list (unw_addr_space_t as, void *table, size_t table_size, - unw_word_t segbase, unw_word_t gp, void *arg) +unw_word_t +libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg) { - return unw_find_dyn_list_p (as, table, table_size, segbase, gp, arg); + return unw_find_dyn_list_p (as, di, arg); } static const struct frame_unwind libunwind_frame_unwind = Index: libunwind-frame.h =================================================================== RCS file: /cvs/src/src/gdb/libunwind-frame.h,v retrieving revision 1.1 diff -u -r1.1 libunwind-frame.h --- libunwind-frame.h 14 Nov 2003 21:17:51 -0000 1.1 +++ libunwind-frame.h 25 Nov 2003 23:48:24 -0000 @@ -55,9 +55,9 @@ int libunwind_search_unwind_table (void *as, long ip, void *di, void *pi, int need_unwind_info, void *args); -unw_word_t libunwind_find_dyn_list (unw_addr_space_t, void *, size_t, - unw_word_t, unw_word_t, void *); - +unw_word_t libunwind_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *, + void *); + #endif /* libunwind-frame.h */ #endif /* HAVE_LIBUNWIND_H */