From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4145 invoked by alias); 5 Apr 2013 13:03:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 4129 invoked by uid 89); 5 Apr 2013 13:03:30 -0000 X-Spam-SWARE-Status: No, score=-4.2 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_XS autolearn=ham version=3.3.1 Received: from na3sys009aog127.obsmtp.com (HELO na3sys009aog127.obsmtp.com) (74.125.149.107) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 05 Apr 2013 13:03:27 +0000 Received: from mx10.qnx.com ([209.226.137.110]) (using TLSv1) by na3sys009aob127.postini.com ([74.125.148.12]) with SMTP ID DSNKUV7Li0d4t5yT/2XDKS171otrN+vClrTd@postini.com; Fri, 05 Apr 2013 06:03:27 PDT Received: by mx10.qnx.com (Postfix, from userid 500) id 5998920E55; Fri, 5 Apr 2013 09:03:04 -0400 (EDT) Received: from exhts.ott.qnx.com (exch1 [10.222.2.137]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mx10.qnx.com (Postfix) with ESMTPS id C77FE20E1B; Fri, 5 Apr 2013 09:03:03 -0400 (EDT) Received: from [10.222.96.215] (10.222.2.5) by EXCH1.ott.qnx.com (10.222.2.137) with Microsoft SMTP Server id 14.2.318.4; Fri, 5 Apr 2013 09:03:03 -0400 Message-ID: <515ECAEF.9000008@qnx.com> Date: Fri, 05 Apr 2013 15:37:00 -0000 From: Aleksandar Ristovski User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130308 Thunderbird/17.0.4 MIME-Version: 1.0 Newsgroups: gmane.comp.gdb.patches To: Jan Kratochvil CC: "gdb-patches@sourceware.org" Subject: Re: [patch 4/6] Prepare linux_find_memory_regions_full & co. for move References: <51278984.3070208@qnx.com> <20130310210820.GE21130@host2.jankratochvil.net> <514C56CB.4070207@qnx.com> <20130326165242.GA12291@host2.jankratochvil.net> <515353C4.2050203@qnx.com> <20130328202805.GB9375@host2.jankratochvil.net> <5159E384.1040709@qnx.com> <20130402130733.GA11748@host2.jankratochvil.net> <515ADD4B.9030409@qnx.com> <20130402133914.GA14816@host2.jankratochvil.net> In-Reply-To: <20130402133914.GA14816@host2.jankratochvil.net> Content-Type: multipart/mixed; boundary="------------080303050506020206030309" X-Virus-Found: No X-SW-Source: 2013-04/txt/msg00123.txt.bz2 --------------080303050506020206030309 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 439 Rebased to master e96bd93d436e464a532a7e1161e1d201c9fc50c7 On 13-04-02 09:39 AM, Jan Kratochvil wrote: > On Tue, 02 Apr 2013 15:29:47 +0200, Aleksandar Ristovski wrote: >> Ok, diff from the code at patch 4 (i.e. after applying patches 1-4) >> that I will incorporate into patch 4 is pasted below. > > Yes... > > >> I did not put any assert in target_fileio_read_alloc_1 - I don't >> think it's useful. > > I agree. > > > Thanks, > Jan > --------------080303050506020206030309 Content-Type: text/x-patch; name="0004-Prepare-linux_find_memory_regions_full-co.-for-move.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0004-Prepare-linux_find_memory_regions_full-co.-for-move.pat"; filename*1="ch" Content-length: 11959 >From 9114031f08b95f2267ed47139aebf047a35edf20 Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Wed, 27 Mar 2013 09:49:36 -0400 Subject: [PATCH 4/8] Prepare linux_find_memory_regions_full & co. for move * linux-tdep.c (linux_find_memory_region_ftype): Comment. (linux_find_memory_regions_full): Change signature and prepare for moving to linux-maps. (linux_find_memory_regions_data): Rename field 'obfd' to 'data'. (linux_find_memory_regions_thunk): New. (linux_find_memory_regions_thunk): Use 'data' field instead of 'obfd'. (linux_find_memory_regions_gdb): New. (linux_find_memory_regions): Rename argument 'obfd' to 'func_data'. (linux_make_mappings_corefile_notes): Use linux_find_memory_regions_gdb. * target.c (target_fileio_read_alloc_1_pread): New function. (read_alloc_pread_ftype): New typedef. (read_alloc): Refactor from target_fileio_read_alloc_1. (target_fileio_read_alloc_1): New implementation. Use read_alloc. (read_stralloc_func_ftype): New typedef. (read_stralloc): Refactored from target_fileio_read_stralloc. (target_fileio_read_stralloc): New implementation, use read_stralloc. --- gdb/linux-tdep.c | 97 ++++++++++++++++++++++++++++++++++++--------------- gdb/target.c | 102 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 141 insertions(+), 58 deletions(-) diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index a132fc6..c48f4ec 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -661,6 +661,10 @@ linux_core_info_proc (struct gdbarch *gdbarch, char *args, error (_("unable to handle request")); } +/* Callback function for linux_find_memory_regions_full. If it returns + non-zero linux_find_memory_regions_full returns immediately with that + value. */ + typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, ULONGEST offset, ULONGEST inode, int read, int write, @@ -668,34 +672,40 @@ typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, const char *filename, void *data); -/* List memory regions in the inferior for a corefile. */ +/* List memory regions in the inferior PID for a corefile. Call FUNC + with FUNC_DATA for each such region. Return immediately with the + value returned by FUNC if it is non-zero. *MEMORY_TO_FREE_PTR should + be registered to be freed automatically if called FUNC throws an + exception. MEMORY_TO_FREE_PTR can be also passed as NULL if it is + not used. Return -1 if error occurs, 0 if all memory regions have + been processed or return the value from FUNC if FUNC returns + non-zero. */ static int -linux_find_memory_regions_full (struct gdbarch *gdbarch, - linux_find_memory_region_ftype *func, - void *obfd) +linux_find_memory_regions_full (pid_t pid, linux_find_memory_region_ftype *func, + void *func_data, void **memory_to_free_ptr) { char filename[100]; - gdb_byte *data; - - /* We need to know the real target PID to access /proc. */ - if (current_inferior ()->fake_pid_p) - return 1; + char *data; - xsnprintf (filename, sizeof filename, - "/proc/%d/smaps", current_inferior ()->pid); + xsnprintf (filename, sizeof filename, "/proc/%d/smaps", (int) pid); data = target_fileio_read_stralloc (filename); if (data == NULL) { /* Older Linux kernels did not support /proc/PID/smaps. */ - xsnprintf (filename, sizeof filename, - "/proc/%d/maps", current_inferior ()->pid); + xsnprintf (filename, sizeof filename, "/proc/%d/maps", (int) pid); data = target_fileio_read_stralloc (filename); } if (data) { - struct cleanup *cleanup = make_cleanup (xfree, data); char *line; + int retval = 0; + + if (memory_to_free_ptr != NULL) + { + gdb_assert (*memory_to_free_ptr == NULL); + *memory_to_free_ptr = data; + } line = strtok (data, "\n"); while (line) @@ -742,15 +752,22 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, modified = 1; /* Invoke the callback function to create the corefile segment. */ - func (addr, endaddr - addr, offset, inode, - read, write, exec, modified, filename, obfd); + retval = func (addr, endaddr - addr, offset, inode, + read, write, exec, modified, filename, func_data); + if (retval != 0) + break; } - do_cleanups (cleanup); - return 0; + if (memory_to_free_ptr != NULL) + { + gdb_assert (data == *memory_to_free_ptr); + *memory_to_free_ptr = NULL; + } + xfree (data); + return retval; } - return 1; + return -1; } /* A structure for passing information through @@ -764,9 +781,11 @@ struct linux_find_memory_regions_data /* The original datum. */ - void *obfd; + void *data; }; +static linux_find_memory_region_ftype linux_find_memory_regions_thunk; + /* A callback for linux_find_memory_regions that converts between the "full"-style callback and find_memory_region_ftype. */ @@ -778,7 +797,30 @@ linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size, { struct linux_find_memory_regions_data *data = arg; - return data->func (vaddr, size, read, write, exec, modified, data->obfd); + return data->func (vaddr, size, read, write, exec, modified, data->data); +} + +/* Wrapper of linux_find_memory_regions_full handling FAKE_PID_P in GDB. */ + +static int +linux_find_memory_regions_gdb (struct gdbarch *gdbarch, + linux_find_memory_region_ftype *func, + void *func_data) +{ + void *memory_to_free = NULL; + struct cleanup *cleanup; + int retval; + + /* We need to know the real target PID so + linux_find_memory_regions_full can access /proc. */ + if (current_inferior ()->fake_pid_p) + return 1; + + cleanup = make_cleanup (free_current_contents, &memory_to_free); + retval = linux_find_memory_regions_full (current_inferior ()->pid, + func, func_data, &memory_to_free); + do_cleanups (cleanup); + return retval; } /* A variant of linux_find_memory_regions_full that is suitable as the @@ -786,16 +828,15 @@ linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size, static int linux_find_memory_regions (struct gdbarch *gdbarch, - find_memory_region_ftype func, void *obfd) + find_memory_region_ftype func, void *func_data) { struct linux_find_memory_regions_data data; data.func = func; - data.obfd = obfd; + data.data = func_data; - return linux_find_memory_regions_full (gdbarch, - linux_find_memory_regions_thunk, - &data); + return linux_find_memory_regions_gdb (gdbarch, + linux_find_memory_regions_thunk, &data); } /* Determine which signal stopped execution. */ @@ -977,8 +1018,8 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, pack_long (buf, long_type, 1); obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type)); - linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback, - &mapping_data); + linux_find_memory_regions_gdb (gdbarch, linux_make_mappings_callback, + &mapping_data); if (mapping_data.file_count != 0) { diff --git a/gdb/target.c b/gdb/target.c index 24cc79d..ed0f3bf 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3476,55 +3476,67 @@ target_fileio_close_cleanup (void *opaque) target_fileio_close (fd, &target_errno); } +/* Helper for target_fileio_read_alloc_1 to make it interruptible. */ + +static int +target_fileio_read_alloc_1_pread (int handle, gdb_byte *read_buf, int len, + ULONGEST offset, int *target_errno) +{ + QUIT; + + return target_fileio_pread (handle, read_buf, len, offset, target_errno); +} + /* Read target file FILENAME. Store the result in *BUF_P and return the size of the transferred data. PADDING additional bytes are available in *BUF_P. This is a helper function for target_fileio_read_alloc; see the declaration of that function for more information. */ +typedef int (read_alloc_pread_ftype) (int handle, gdb_byte *read_buf, int len, + ULONGEST offset, int *target_errno); + static LONGEST -target_fileio_read_alloc_1 (const char *filename, - gdb_byte **buf_p, int padding) +read_alloc (gdb_byte **buf_p, int handle, read_alloc_pread_ftype *pread_func, + int padding, void **memory_to_free_ptr) { - struct cleanup *close_cleanup; size_t buf_alloc, buf_pos; gdb_byte *buf; LONGEST n; - int fd; int target_errno; - fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno); - if (fd == -1) - return -1; - - close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd); - /* Start by reading up to 4K at a time. The target will throttle this number down if necessary. */ buf_alloc = 4096; buf = xmalloc (buf_alloc); + if (memory_to_free_ptr != NULL) + { + gdb_assert (*memory_to_free_ptr == NULL); + *memory_to_free_ptr = buf; + } buf_pos = 0; while (1) { - n = target_fileio_pread (fd, &buf[buf_pos], - buf_alloc - buf_pos - padding, buf_pos, - &target_errno); - if (n < 0) + n = pread_func (handle, &buf[buf_pos], buf_alloc - buf_pos - padding, + buf_pos, &target_errno); + if (n <= 0) { - /* An error occurred. */ - do_cleanups (close_cleanup); - xfree (buf); - return -1; - } - else if (n == 0) - { - /* Read all there was. */ - do_cleanups (close_cleanup); - if (buf_pos == 0) + if (n < 0 || (n == 0 && buf_pos == 0)) xfree (buf); else *buf_p = buf; - return buf_pos; + if (memory_to_free_ptr != NULL) + *memory_to_free_ptr = NULL; + if (n < 0) + { + /* An error occurred. */ + return -1; + } + else + { + /* Read all there was. */ + return buf_pos; + } } buf_pos += n; @@ -3534,12 +3546,34 @@ target_fileio_read_alloc_1 (const char *filename, { buf_alloc *= 2; buf = xrealloc (buf, buf_alloc); + if (memory_to_free_ptr != NULL) + *memory_to_free_ptr = buf; } - - QUIT; } } +static LONGEST +target_fileio_read_alloc_1 (const char *filename, + gdb_byte **buf_p, int padding) +{ + struct cleanup *close_cleanup; + int fd, target_errno; + void *memory_to_free = NULL; + LONGEST retval; + + fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno); + if (fd == -1) + return -1; + + close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd); + + make_cleanup (free_current_contents, &memory_to_free); + retval = read_alloc (buf_p, fd, target_fileio_read_alloc_1_pread, padding, + &memory_to_free); + do_cleanups (close_cleanup); + return retval; +} + /* Read target file FILENAME. Store the result in *BUF_P and return the size of the transferred data. See the declaration in "target.h" function for more information about the return value. */ @@ -3556,14 +3590,17 @@ target_fileio_read_alloc (const char *filename, gdb_byte **buf_p) are returned as allocated but empty strings. A warning is issued if the result contains any embedded NUL bytes. */ -char * -target_fileio_read_stralloc (const char *filename) +typedef LONGEST (read_stralloc_func_ftype) (const char *filename, + gdb_byte **buf_p, int padding); + +static char * +read_stralloc (const char *filename, read_stralloc_func_ftype *func) { gdb_byte *buffer; char *bufstr; LONGEST i, transferred; - transferred = target_fileio_read_alloc_1 (filename, &buffer, 1); + transferred = func (filename, &buffer, 1); bufstr = (char *) buffer; if (transferred < 0) @@ -3587,6 +3624,11 @@ target_fileio_read_stralloc (const char *filename) return bufstr; } +char * +target_fileio_read_stralloc (const char *filename) +{ + return read_stralloc (filename, target_fileio_read_alloc_1); +} static int default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) -- 1.7.10.4 --------------080303050506020206030309-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30141 invoked by alias); 6 Apr 2013 19:10:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 30128 invoked by uid 89); 6 Apr 2013 19:10:50 -0000 X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,DATE_IN_PAST_24_48,FSL_HELO_BARE_IP_2,KHOP_THREADED,RCVD_IN_DNSWL_NONE,RCVD_NUMERIC_HELO,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_XS autolearn=ham version=3.3.1 Received: from plane.gmane.org (HELO plane.gmane.org) (80.91.229.3) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sat, 06 Apr 2013 19:10:47 +0000 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1UOYK5-0007TC-8K for gdb-patches@sourceware.org; Sat, 06 Apr 2013 20:58:45 +0200 Received: from 209.226.137.106 ([209.226.137.106]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 06 Apr 2013 20:58:45 +0200 Received: from ARistovski by 209.226.137.106 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 06 Apr 2013 20:58:45 +0200 To: gdb-patches@sourceware.org From: Aleksandar Ristovski Subject: Re: [patch 4/6] Prepare linux_find_memory_regions_full & co. for move Date: Sun, 07 Apr 2013 14:28:00 -0000 Message-ID: <515ECAEF.9000008@qnx.com> References: <51278984.3070208@qnx.com> <20130310210820.GE21130@host2.jankratochvil.net> <514C56CB.4070207@qnx.com> <20130326165242.GA12291@host2.jankratochvil.net> <515353C4.2050203@qnx.com> <20130328202805.GB9375@host2.jankratochvil.net> <5159E384.1040709@qnx.com> <20130402130733.GA11748@host2.jankratochvil.net> <515ADD4B.9030409@qnx.com> <20130402133914.GA14816@host2.jankratochvil.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------080303050506020206030309" Cc: "gdb-patches@sourceware.org" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130308 Thunderbird/17.0.4 In-Reply-To: <20130402133914.GA14816@host2.jankratochvil.net> X-Virus-Found: No X-SW-Source: 2013-04/txt/msg00163.txt.bz2 Message-ID: <20130407142800._SWmhSA95V81IdxPoxf66Q6V9WhppplHHzAB9c8EhzA@z> This is a multi-part message in MIME format. --------------080303050506020206030309 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 439 Rebased to master e96bd93d436e464a532a7e1161e1d201c9fc50c7 On 13-04-02 09:39 AM, Jan Kratochvil wrote: > On Tue, 02 Apr 2013 15:29:47 +0200, Aleksandar Ristovski wrote: >> Ok, diff from the code at patch 4 (i.e. after applying patches 1-4) >> that I will incorporate into patch 4 is pasted below. > > Yes... > > >> I did not put any assert in target_fileio_read_alloc_1 - I don't >> think it's useful. > > I agree. > > > Thanks, > Jan > --------------080303050506020206030309 Content-Type: text/x-patch; name="0004-Prepare-linux_find_memory_regions_full-co.-for-move.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0004-Prepare-linux_find_memory_regions_full-co.-for-move.pat"; filename*1="ch" Content-length: 11959 >From 9114031f08b95f2267ed47139aebf047a35edf20 Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Wed, 27 Mar 2013 09:49:36 -0400 Subject: [PATCH 4/8] Prepare linux_find_memory_regions_full & co. for move * linux-tdep.c (linux_find_memory_region_ftype): Comment. (linux_find_memory_regions_full): Change signature and prepare for moving to linux-maps. (linux_find_memory_regions_data): Rename field 'obfd' to 'data'. (linux_find_memory_regions_thunk): New. (linux_find_memory_regions_thunk): Use 'data' field instead of 'obfd'. (linux_find_memory_regions_gdb): New. (linux_find_memory_regions): Rename argument 'obfd' to 'func_data'. (linux_make_mappings_corefile_notes): Use linux_find_memory_regions_gdb. * target.c (target_fileio_read_alloc_1_pread): New function. (read_alloc_pread_ftype): New typedef. (read_alloc): Refactor from target_fileio_read_alloc_1. (target_fileio_read_alloc_1): New implementation. Use read_alloc. (read_stralloc_func_ftype): New typedef. (read_stralloc): Refactored from target_fileio_read_stralloc. (target_fileio_read_stralloc): New implementation, use read_stralloc. --- gdb/linux-tdep.c | 97 ++++++++++++++++++++++++++++++++++++--------------- gdb/target.c | 102 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 141 insertions(+), 58 deletions(-) diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index a132fc6..c48f4ec 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -661,6 +661,10 @@ linux_core_info_proc (struct gdbarch *gdbarch, char *args, error (_("unable to handle request")); } +/* Callback function for linux_find_memory_regions_full. If it returns + non-zero linux_find_memory_regions_full returns immediately with that + value. */ + typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, ULONGEST offset, ULONGEST inode, int read, int write, @@ -668,34 +672,40 @@ typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, const char *filename, void *data); -/* List memory regions in the inferior for a corefile. */ +/* List memory regions in the inferior PID for a corefile. Call FUNC + with FUNC_DATA for each such region. Return immediately with the + value returned by FUNC if it is non-zero. *MEMORY_TO_FREE_PTR should + be registered to be freed automatically if called FUNC throws an + exception. MEMORY_TO_FREE_PTR can be also passed as NULL if it is + not used. Return -1 if error occurs, 0 if all memory regions have + been processed or return the value from FUNC if FUNC returns + non-zero. */ static int -linux_find_memory_regions_full (struct gdbarch *gdbarch, - linux_find_memory_region_ftype *func, - void *obfd) +linux_find_memory_regions_full (pid_t pid, linux_find_memory_region_ftype *func, + void *func_data, void **memory_to_free_ptr) { char filename[100]; - gdb_byte *data; - - /* We need to know the real target PID to access /proc. */ - if (current_inferior ()->fake_pid_p) - return 1; + char *data; - xsnprintf (filename, sizeof filename, - "/proc/%d/smaps", current_inferior ()->pid); + xsnprintf (filename, sizeof filename, "/proc/%d/smaps", (int) pid); data = target_fileio_read_stralloc (filename); if (data == NULL) { /* Older Linux kernels did not support /proc/PID/smaps. */ - xsnprintf (filename, sizeof filename, - "/proc/%d/maps", current_inferior ()->pid); + xsnprintf (filename, sizeof filename, "/proc/%d/maps", (int) pid); data = target_fileio_read_stralloc (filename); } if (data) { - struct cleanup *cleanup = make_cleanup (xfree, data); char *line; + int retval = 0; + + if (memory_to_free_ptr != NULL) + { + gdb_assert (*memory_to_free_ptr == NULL); + *memory_to_free_ptr = data; + } line = strtok (data, "\n"); while (line) @@ -742,15 +752,22 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch, modified = 1; /* Invoke the callback function to create the corefile segment. */ - func (addr, endaddr - addr, offset, inode, - read, write, exec, modified, filename, obfd); + retval = func (addr, endaddr - addr, offset, inode, + read, write, exec, modified, filename, func_data); + if (retval != 0) + break; } - do_cleanups (cleanup); - return 0; + if (memory_to_free_ptr != NULL) + { + gdb_assert (data == *memory_to_free_ptr); + *memory_to_free_ptr = NULL; + } + xfree (data); + return retval; } - return 1; + return -1; } /* A structure for passing information through @@ -764,9 +781,11 @@ struct linux_find_memory_regions_data /* The original datum. */ - void *obfd; + void *data; }; +static linux_find_memory_region_ftype linux_find_memory_regions_thunk; + /* A callback for linux_find_memory_regions that converts between the "full"-style callback and find_memory_region_ftype. */ @@ -778,7 +797,30 @@ linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size, { struct linux_find_memory_regions_data *data = arg; - return data->func (vaddr, size, read, write, exec, modified, data->obfd); + return data->func (vaddr, size, read, write, exec, modified, data->data); +} + +/* Wrapper of linux_find_memory_regions_full handling FAKE_PID_P in GDB. */ + +static int +linux_find_memory_regions_gdb (struct gdbarch *gdbarch, + linux_find_memory_region_ftype *func, + void *func_data) +{ + void *memory_to_free = NULL; + struct cleanup *cleanup; + int retval; + + /* We need to know the real target PID so + linux_find_memory_regions_full can access /proc. */ + if (current_inferior ()->fake_pid_p) + return 1; + + cleanup = make_cleanup (free_current_contents, &memory_to_free); + retval = linux_find_memory_regions_full (current_inferior ()->pid, + func, func_data, &memory_to_free); + do_cleanups (cleanup); + return retval; } /* A variant of linux_find_memory_regions_full that is suitable as the @@ -786,16 +828,15 @@ linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size, static int linux_find_memory_regions (struct gdbarch *gdbarch, - find_memory_region_ftype func, void *obfd) + find_memory_region_ftype func, void *func_data) { struct linux_find_memory_regions_data data; data.func = func; - data.obfd = obfd; + data.data = func_data; - return linux_find_memory_regions_full (gdbarch, - linux_find_memory_regions_thunk, - &data); + return linux_find_memory_regions_gdb (gdbarch, + linux_find_memory_regions_thunk, &data); } /* Determine which signal stopped execution. */ @@ -977,8 +1018,8 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, pack_long (buf, long_type, 1); obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type)); - linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback, - &mapping_data); + linux_find_memory_regions_gdb (gdbarch, linux_make_mappings_callback, + &mapping_data); if (mapping_data.file_count != 0) { diff --git a/gdb/target.c b/gdb/target.c index 24cc79d..ed0f3bf 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3476,55 +3476,67 @@ target_fileio_close_cleanup (void *opaque) target_fileio_close (fd, &target_errno); } +/* Helper for target_fileio_read_alloc_1 to make it interruptible. */ + +static int +target_fileio_read_alloc_1_pread (int handle, gdb_byte *read_buf, int len, + ULONGEST offset, int *target_errno) +{ + QUIT; + + return target_fileio_pread (handle, read_buf, len, offset, target_errno); +} + /* Read target file FILENAME. Store the result in *BUF_P and return the size of the transferred data. PADDING additional bytes are available in *BUF_P. This is a helper function for target_fileio_read_alloc; see the declaration of that function for more information. */ +typedef int (read_alloc_pread_ftype) (int handle, gdb_byte *read_buf, int len, + ULONGEST offset, int *target_errno); + static LONGEST -target_fileio_read_alloc_1 (const char *filename, - gdb_byte **buf_p, int padding) +read_alloc (gdb_byte **buf_p, int handle, read_alloc_pread_ftype *pread_func, + int padding, void **memory_to_free_ptr) { - struct cleanup *close_cleanup; size_t buf_alloc, buf_pos; gdb_byte *buf; LONGEST n; - int fd; int target_errno; - fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno); - if (fd == -1) - return -1; - - close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd); - /* Start by reading up to 4K at a time. The target will throttle this number down if necessary. */ buf_alloc = 4096; buf = xmalloc (buf_alloc); + if (memory_to_free_ptr != NULL) + { + gdb_assert (*memory_to_free_ptr == NULL); + *memory_to_free_ptr = buf; + } buf_pos = 0; while (1) { - n = target_fileio_pread (fd, &buf[buf_pos], - buf_alloc - buf_pos - padding, buf_pos, - &target_errno); - if (n < 0) + n = pread_func (handle, &buf[buf_pos], buf_alloc - buf_pos - padding, + buf_pos, &target_errno); + if (n <= 0) { - /* An error occurred. */ - do_cleanups (close_cleanup); - xfree (buf); - return -1; - } - else if (n == 0) - { - /* Read all there was. */ - do_cleanups (close_cleanup); - if (buf_pos == 0) + if (n < 0 || (n == 0 && buf_pos == 0)) xfree (buf); else *buf_p = buf; - return buf_pos; + if (memory_to_free_ptr != NULL) + *memory_to_free_ptr = NULL; + if (n < 0) + { + /* An error occurred. */ + return -1; + } + else + { + /* Read all there was. */ + return buf_pos; + } } buf_pos += n; @@ -3534,12 +3546,34 @@ target_fileio_read_alloc_1 (const char *filename, { buf_alloc *= 2; buf = xrealloc (buf, buf_alloc); + if (memory_to_free_ptr != NULL) + *memory_to_free_ptr = buf; } - - QUIT; } } +static LONGEST +target_fileio_read_alloc_1 (const char *filename, + gdb_byte **buf_p, int padding) +{ + struct cleanup *close_cleanup; + int fd, target_errno; + void *memory_to_free = NULL; + LONGEST retval; + + fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno); + if (fd == -1) + return -1; + + close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd); + + make_cleanup (free_current_contents, &memory_to_free); + retval = read_alloc (buf_p, fd, target_fileio_read_alloc_1_pread, padding, + &memory_to_free); + do_cleanups (close_cleanup); + return retval; +} + /* Read target file FILENAME. Store the result in *BUF_P and return the size of the transferred data. See the declaration in "target.h" function for more information about the return value. */ @@ -3556,14 +3590,17 @@ target_fileio_read_alloc (const char *filename, gdb_byte **buf_p) are returned as allocated but empty strings. A warning is issued if the result contains any embedded NUL bytes. */ -char * -target_fileio_read_stralloc (const char *filename) +typedef LONGEST (read_stralloc_func_ftype) (const char *filename, + gdb_byte **buf_p, int padding); + +static char * +read_stralloc (const char *filename, read_stralloc_func_ftype *func) { gdb_byte *buffer; char *bufstr; LONGEST i, transferred; - transferred = target_fileio_read_alloc_1 (filename, &buffer, 1); + transferred = func (filename, &buffer, 1); bufstr = (char *) buffer; if (transferred < 0) @@ -3587,6 +3624,11 @@ target_fileio_read_stralloc (const char *filename) return bufstr; } +char * +target_fileio_read_stralloc (const char *filename) +{ + return read_stralloc (filename, target_fileio_read_alloc_1); +} static int default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) -- 1.7.10.4 --------------080303050506020206030309--