From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2717 invoked by alias); 9 Jan 2008 08:53:13 -0000 Received: (qmail 2709 invoked by uid 22791); 9 Jan 2008 08:53:12 -0000 X-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_37,J_CHICKENPOX_74 X-Spam-Check-By: sourceware.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (83.160.170.119) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 09 Jan 2008 08:52:55 +0000 Received: from dijkstra.wildebeest.org ([192.168.1.29]) by gnu.wildebeest.org with esmtp (Exim 4.63) (envelope-from ) id 1JCWg7-0001vv-Bh for frysk@sourceware.org; Wed, 09 Jan 2008 09:52:52 +0100 Subject: [patch] Use only eh_frame data for libunwind get_unwind_table From: Mark Wielaard To: frysk Content-Type: multipart/mixed; boundary="=-5rnm+4Jg03ow0XPN6LhA" Date: Wed, 09 Jan 2008 08:53:00 -0000 Message-Id: <1199868771.3118.27.camel@dijkstra.wildebeest.org> Mime-Version: 1.0 X-Mailer: Evolution 2.12.2 (2.12.2-2.fc8) X-Spam-Score: -4.4 (----) X-Virus-Checked: Checked by ClamAV on sourceware.org X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2008-q1/txt/msg00014.txt.bz2 --=-5rnm+4Jg03ow0XPN6LhA Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 1780 Hi, We used to have a somewhat awkward get_unwind_table interface where we passed both the (fake) address space of the unwind table as the original vaddr of the table. This was necessary because eh_frames contain pc-relative addresses, so libunwind wanted to get the original address. This patch makes it so that the address space we pass to libunwind has the correct relative addresses, so no extra arguments are necessary for libunwind to adjust anything. There is one local libunwind patch necessary for now to make this work. That is to not directly read the the personality routine address from the CIE since it can be stored anywhere and currently we are just feeding it the unwind table data. We still need to read the encoded pointer to get past it. This can be restored when frysk feeds the eh_frame through its main address space. We never use the personality routine inside Frysk at the moment. frysk-imports/libunwind/ChangeLog 2007-12-22 Mark Wielaard * include/libunwind-common.h.in (unw_get_unwind_table): Remove as, arg and peh_vaddr arguments. * src/mi/Gget_unwind_table.c (unw_get_unwind_table): Likewise. Create address space from eh_frame_accessors. Set rti.table_data and rti.segbase from eh_frame_hdr_address. Pass eh_frame_arg to tdep_search_unwind_table. * src/dwarf/Gfde.c (parse_cie): Add FRYSK LOCAL hack to not read personality routine address. frysk-sys/lib/unwind/ChangeLog 2007-12-22 Mark Wielaard * cni/UnwindH.hxx (get_eh_frame_hdr_addr): Return char*. (createProcInfoFromElfImage): Calculate virtual and adjusted addresses from eh_table_hdr and peh_vaddr. Tested on x86 and x86_64. Committed, Mark --=-5rnm+4Jg03ow0XPN6LhA Content-Disposition: inline; filename=pc-rel.patch Content-Type: text/x-patch; name=pc-rel.patch; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-length: 5334 --- a/frysk-imports/libunwind/include/libunwind-common.h.in +++ b/frysk-imports/libunwind/include/libunwind-common.h.in @@ -250,12 +250,10 @@ extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *); extern int unw_is_signal_frame (unw_cursor_t *); extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *); extern const char *unw_strerror (int); -extern int unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, +extern int unw_get_unwind_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info, - void *arg, unw_accessors_t *eh_frame_accessors, unw_word_t eh_frame_hdr_address, - void *eh_frame_arg, - unw_word_t peh_vaddr); + void *eh_frame_arg); extern unw_addr_space_t unw_local_addr_space; diff --git a/frysk-imports/libunwind/src/dwarf/Gfde.c b/frysk-imports/libunwind/src/dwarf/Gfde.c index d6b4987..11a6433 100644 --- a/frysk-imports/libunwind/src/dwarf/Gfde.c +++ b/frysk-imports/libunwind/src/dwarf/Gfde.c @@ -173,6 +173,15 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr, /* read the personality-routine pointer-encoding format. */ if ((ret = dwarf_readu8 (as, a, &addr, &handler_encoding, arg)) < 0) return ret; + // FRYSK LOCAL + // We never want to actually read the personality routine address + // since it can be stored anywhere and currently we are just + // feeding it the unwind table data. We still need to read the + // encoded pointer to get past it. + // Can be restored when frysk feeds the eh_frame through its + // main address space. + handler_encoding &= ~DW_EH_PE_indirect; + // END FRYSK LOCAL if ((ret = dwarf_read_encoded_pointer (as, a, &addr, handler_encoding, pi, &dci->handler, arg)) < 0) return ret; diff --git a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c index 1d905b6..fc46269 100644 --- a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c +++ b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c @@ -26,14 +26,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "dwarf-eh.h" int -unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, - unw_proc_info_t *pi, int need_unwind_info, void *arg, +unw_get_unwind_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info, unw_accessors_t *eh_frame_accessors, unw_word_t eh_frame_hdr_address, - void *eh_frame_arg, - unw_word_t peh_vaddr) + void *eh_frame_arg) { int ret; + unw_addr_space_t as = unw_create_addr_space (eh_frame_accessors, 0); unw_word_t start = eh_frame_hdr_address; // Version @@ -83,11 +82,12 @@ unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, di.u.rti.name_ptr = 0; /* two 32-bit values (ip_offset/fde_offset) per table-entry: For the binary-search table in the eh_frame_hdr, data-relative - means relative to the start of that section... - So for now we pass in peh_vaddr and use the main as for access. */ + means relative to the start of that section... */ di.u.rti.table_len = (fde_count * 8) / sizeof (unw_word_t); - di.u.rti.table_data = peh_vaddr + 12; - di.u.rti.segbase = peh_vaddr; + di.u.rti.table_data = eh_frame_hdr_address + 12; + di.u.rti.segbase = eh_frame_hdr_address; - return tdep_search_unwind_table (as, ip, &di, pi, need_unwind_info, arg); + ret = tdep_search_unwind_table (as, ip, &di, pi, need_unwind_info, + eh_frame_arg); + return ret; } diff --git a/frysk-sys/lib/unwind/cni/UnwindH.hxx b/frysk-sys/lib/unwind/cni/UnwindH.hxx index 7dbcf7b..e69e031 100644 --- a/frysk-sys/lib/unwind/cni/UnwindH.hxx +++ b/frysk-sys/lib/unwind/cni/UnwindH.hxx @@ -446,7 +446,7 @@ lib::unwind::TARGET::getProcInfo(gnu::gcj::RawDataManaged* cursor) // Also fills in ip->start_ip, ip->end_ip and ip->gp. // peh_vaddr will point to the address of the eh_frame_hdr in the main // address space of the inferior. -static void * +static char * get_eh_frame_hdr_addr(unw_proc_info_t *pi, char *image, size_t size, unsigned long segbase, unw_word_t *peh_vaddr) { @@ -582,12 +582,10 @@ lib::unwind::TARGET::createProcInfoFromElfImage(lib::unwind::AddressSpace* addre unw_proc_info_t *procInfo = (::unw_proc_info_t *) JvAllocBytes(sizeof (::unw_proc_info_t)); - unw_addr_space_t as = (unw_addr_space_t) addressSpace->addressSpace; - logFine(this, logger, "Pre unw_get_unwind_table"); unw_word_t peh_vaddr = 0; - void *eh_table_hdr = get_eh_frame_hdr_addr(procInfo, + char *eh_table_hdr = get_eh_frame_hdr_addr(procInfo, (char *) elfImage->elfImage, elfImage->size, elfImage->segbase, @@ -602,16 +600,14 @@ lib::unwind::TARGET::createProcInfoFromElfImage(lib::unwind::AddressSpace* addre if (eh_table_hdr == NULL) return new lib::unwind::ProcInfo(-UNW_ENOINFO); - int ret = unw_get_unwind_table(as, - (unw_word_t) ip, + int ret = unw_get_unwind_table((unw_word_t) ip, procInfo, (int) needUnwindInfo, - (void *) addressSpace, &local_accessors, - 0, - eh_table_hdr, - peh_vaddr); - + // virtual address + peh_vaddr, + // address adjustment + eh_table_hdr - peh_vaddr); logFine(this, logger, "Post unw_get_unwind_table"); lib::unwind::ProcInfo *myInfo; --=-5rnm+4Jg03ow0XPN6LhA--