From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17280 invoked by alias); 29 Nov 2007 11:20:28 -0000 Received: (qmail 17273 invoked by uid 22791); 29 Nov 2007 11:20:27 -0000 X-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,DK_POLICY_SIGNSOME,FORGED_RCVD_HELO,TW_PT 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; Thu, 29 Nov 2007 11:20:20 +0000 Received: from dijkstra.wildebeest.org ([192.168.1.29]) by gnu.wildebeest.org with esmtp (Exim 4.63) (envelope-from ) id 1IxhRF-0004DS-W9 for frysk@sourceware.org; Thu, 29 Nov 2007 12:20:15 +0100 Subject: Make libunwind a little bit more 64bit safe From: Mark Wielaard To: frysk Content-Type: multipart/mixed; boundary="=-8mgNnGgwwP3xyV7/t0md" Date: Thu, 29 Nov 2007 11:20:00 -0000 Message-Id: <1196335213.27594.27.camel@dijkstra.wildebeest.org> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 (2.12.1-3.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: 2007-q4/txt/msg00191.txt.bz2 --=-8mgNnGgwwP3xyV7/t0md Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 1665 Hi, One of the issues we had with libunwind for 32-on-64 unwinding was that there are some parts that need access to local 64bit memory, but defined an unw_word_t as wide as the target (32 bit). This patch makes it so that for those parts we now use an address space that is indexed of a 64bit pointer (passed as arg to the accessor methods). And gets rid of the MAP_32BIT hacks we had. When we push this upstream, we should do the same for the libunwind ptrace backend to show why it is useful. But I didn't want to spend too much time on that now since we don't use it in frysk. frysk-imports/libunwind/ChangeLog 2007-11-28 Mark Wielaard * src/mi/Gget_unwind_table.c (unw_get_unwind_table): Make addr a char *, pass addr as arg to dwarf_read functions, make local_access_mem use arg as base address for start indexed reads. frysk-sys/lib/unwind/ChangeLog 2007-11-29 Mark Wielaard * cni/ElfImage.cxx: Don't define MAP_32BIT. (mapElfImage): Don't use MAP_32BIT. * cni/UnwindH.hxx: Don't define MAP_32BIT. (createElfImageFromVDSO): Don't use MAP_32BIT. Tested by also running all -arch 32 tests on a 64bit system (and also straight make check on x86 and x86_64). It would be nicer if we didn't need to feed an elfimage to libunwind and libunwind didn't try to do the elf parsing itself here. But when we feed it debug_frame info we will have the table come not from the inferior memory directly anyway, so for now it is useful (although ideally libunwind would just accept a pointer or addressspace reference to the debug_frame or debug_info table and use that). Cheers, Mark --=-8mgNnGgwwP3xyV7/t0md Content-Disposition: inline; filename=32vs64libunwind.patch Content-Type: text/x-patch; name=32vs64libunwind.patch; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-length: 5626 diff --git a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c index 3f71bb3..2acb947 100644 --- a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c +++ b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c @@ -32,7 +32,8 @@ unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, { Debug(99, "Entering get_unwind_table\n"); Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL; - unw_word_t addr, eh_frame_start, fde_count, load_base; + unw_word_t eh_frame_start, fde_count, load_base; + char *addr; struct dwarf_eh_frame_hdr *hdr; Elf_W(Ehdr) *ehdr; int i, ret; @@ -110,7 +111,7 @@ unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, Debug(99, "EH_VERSION is correct\n"); - addr = (unw_word_t) (hdr + 1); + addr = hdr + 1; Debug (99, "Got addr\n"); /* Fill in a dummy proc_info structure. We just need to fill in enough to ensure that dwarf_read_encoded_pointer() can do it's @@ -122,45 +123,48 @@ unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, Debug(99, "set pi gp\n"); - -//The following is a dummy local address space used by dwarf_read_encoded_pointer. +// The following is a local address space memory accessor used by +// dwarf_read_encoded_pointer. The arg pointer is the base address, +// addr is the offset from the base address. int local_access_mem (unw_addr_space_t as, unw_word_t addr, - unw_word_t *val, int write, void *arg) + unw_word_t *val, int write, void *arg) { - Debug(99, "entering local_access_mem, reading addr: 0x%lx into: %p\n", - (long) addr, val); - if (write) - { - Debug (16, "mem[%x] <- %x\n", addr, *val); - *(unw_word_t *) addr = *val; - } - else - { - *val = *(unw_word_t *) addr; - Debug (16, "mem[%x] -> %x\n", addr, *val); - } - Debug(99, "leaving local_access_mem\n"); - return 0; + Debug(99, "entering local_access_mem, reading addr: 0x%lx into: %p\n", + (long) addr, val); + if (write) + { + // Writing is not supported + return -UNW_EINVAL; + } + else + { + *val = *(unw_word_t *) (addr + (char *) arg); + Debug (16, "mem[%x] -> %x\n", (addr + (char *) arg), *val); + } + Debug(99, "leaving local_access_mem\n"); + return 0; } - unw_accessors_t temp_local_accessors = {NULL, NULL, NULL, local_access_mem, - NULL, NULL, NULL, NULL, NULL}; - unw_addr_space_t temp_local_addr_space - = unw_create_addr_space(&temp_local_accessors, 0); + unw_accessors_t local_accessors = {NULL, NULL, NULL, local_access_mem, + NULL, NULL, NULL, NULL, NULL}; + unw_addr_space_t local_addr_space + = unw_create_addr_space(&local_accessors, 0); + + unw_word_t start = 0; /* (Optionally) read eh_frame_ptr: */ - if ((ret = dwarf_read_encoded_pointer (temp_local_addr_space, &temp_local_accessors, - &addr, hdr->eh_frame_ptr_enc, pi, - &eh_frame_start, NULL)) < 0) + if ((ret = dwarf_read_encoded_pointer (local_addr_space, &local_accessors, + &start, hdr->eh_frame_ptr_enc, pi, + &eh_frame_start, addr)) < 0) return -1; Debug(99, "read eh_frame_start: 0x%lx\n", (long) eh_frame_start); /* (Optionally) read fde_count: */ - if ((ret = dwarf_read_encoded_pointer (temp_local_addr_space, &temp_local_accessors, - &addr, hdr->fde_count_enc, pi, - &fde_count, NULL)) < 0) + if ((ret = dwarf_read_encoded_pointer (local_addr_space, &local_accessors, + &start, hdr->fde_count_enc, pi, + &fde_count, addr)) < 0) return -1; Debug(99, "read fde_count: 0x%lx\n", (long) fde_count); @@ -169,7 +173,9 @@ unw_get_unwind_table(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, return -1; } - load_base = segbase - ptxt->p_vaddr; + addr += start; + + load_base = segbase - ptxt->p_vaddr; di_cache.start_ip = segbase; di_cache.end_ip = di_cache.start_ip + ptxt->p_memsz; diff --git a/frysk-sys/lib/unwind/cni/ElfImage.cxx b/frysk-sys/lib/unwind/cni/ElfImage.cxx index bda8e25..d521643 100644 --- a/frysk-sys/lib/unwind/cni/ElfImage.cxx +++ b/frysk-sys/lib/unwind/cni/ElfImage.cxx @@ -48,10 +48,6 @@ #include "lib/unwind/ElfImage.h" -#ifndef MAP_32BIT -#define MAP_32BIT 0 -#endif - lib::unwind::ElfImage* lib::unwind::ElfImage::mapElfImage(jstring elfImageName, jlong segbase, jlong hi, jlong mapoff) @@ -77,8 +73,7 @@ lib::unwind::ElfImage::mapElfImage(jstring elfImageName, jlong segbase, jlong hi } size = stat.st_size; - image = mmap (NULL, size, PROT_READ, MAP_PRIVATE | MAP_32BIT, fd, 0); - + image = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); close (fd); if (image == MAP_FAILED) diff --git a/frysk-sys/lib/unwind/cni/UnwindH.hxx b/frysk-sys/lib/unwind/cni/UnwindH.hxx index 77a24cf..7be5254 100644 --- a/frysk-sys/lib/unwind/cni/UnwindH.hxx +++ b/frysk-sys/lib/unwind/cni/UnwindH.hxx @@ -77,10 +77,6 @@ # define MAX_VDSO_SIZE ((size_t) sysconf (_SC_PAGESIZE)) #endif -#ifndef MAP_32BIT -# define MAP_32BIT 0 -#endif - static lib::unwind::AddressSpace* addressSpace(void* arg) { @@ -477,7 +473,7 @@ lib::unwind::TARGET::createElfImageFromVDSO(lib::unwind::AddressSpace* addressSp logFine(this, logger, "checked magic size"); image = mmap (0, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (image == MAP_FAILED) return new lib::unwind::ElfImage((jint) -1); --=-8mgNnGgwwP3xyV7/t0md--