From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28130 invoked by alias); 27 Mar 2013 20:17:47 -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 28081 invoked by uid 89); 27 Mar 2013 20:17:40 -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 na3sys009aog137.obsmtp.com (HELO na3sys009aog137.obsmtp.com) (74.125.149.18) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 27 Mar 2013 20:17:35 +0000 Received: from mx10.qnx.com ([209.226.137.110]) (using TLSv1) by na3sys009aob137.postini.com ([74.125.148.12]) with SMTP ID DSNKUVNT3U+32w1NE9ilPEK2EJmXVuWinxUO@postini.com; Wed, 27 Mar 2013 13:17:35 PDT Received: by mx10.qnx.com (Postfix, from userid 500) id 9908520E42; Wed, 27 Mar 2013 16:17:32 -0400 (EDT) Received: from exhts.ott.qnx.com (exch2 [10.222.2.136]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mx10.qnx.com (Postfix) with ESMTPS id EBD7C209E9; Wed, 27 Mar 2013 16:17:31 -0400 (EDT) Received: from [10.222.96.215] (10.222.2.5) by exch2.ott.qnx.com (10.222.2.136) with Microsoft SMTP Server id 14.2.318.4; Wed, 27 Mar 2013 16:17:31 -0400 Message-ID: <515353C4.2050203@qnx.com> Date: Wed, 27 Mar 2013 20:44: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> In-Reply-To: <20130326165242.GA12291@host2.jankratochvil.net> Content-Type: multipart/mixed; boundary="------------090502070409060408090108" X-Virus-Found: No X-SW-Source: 2013-03/txt/msg01038.txt.bz2 --------------090502070409060408090108 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 240 New patch #4/6. Changed: read_stralloc is now refactored here, rather than in #5/6 where it gets moved, so that move remains clean in #5. Similarly, the change for linux_find_memory_regions_full moved from #5 here. Thanks, Aleksandar --------------090502070409060408090108 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: 12626 >From 8c30427ad466b50bdfe3e0e8cf9609545fcc3e4c Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Wed, 27 Mar 2013 09:49:36 -0400 Subject: [PATCH 4/6] 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 | 122 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 153 insertions(+), 66 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 9193c97..2195d0b 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3460,55 +3460,73 @@ 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) - xfree (buf); + if (n < 0 || (n == 0 && buf_pos == 0)) + { + if (memory_to_free_ptr != NULL) + { + gdb_assert (buf == *memory_to_free_ptr); + *memory_to_free_ptr = NULL; + } + xfree (buf); + } else *buf_p = buf; - return buf_pos; + + if (n < 0) + { + /* An error occurred. */ + return -1; + } + else + { + /* Read all there was. */ + return buf_pos; + } } buf_pos += n; @@ -3518,12 +3536,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. */ @@ -3540,15 +3580,16 @@ 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; + char *buffer; LONGEST i, transferred; - transferred = target_fileio_read_alloc_1 (filename, &buffer, 1); - bufstr = (char *) buffer; + transferred = func (filename, (gdb_byte **) &buffer, 1); if (transferred < 0) return NULL; @@ -3556,11 +3597,11 @@ target_fileio_read_stralloc (const char *filename) if (transferred == 0) return xstrdup (""); - bufstr[transferred] = 0; + buffer[transferred] = 0; /* Check for embedded NUL bytes; but allow trailing NULs. */ - for (i = strlen (bufstr); i < transferred; i++) - if (bufstr[i] != 0) + for (i = strlen (buffer); i < transferred; i++) + if (buffer[i] != 0) { warning (_("target file %s " "contained unexpected null characters"), @@ -3568,9 +3609,14 @@ target_fileio_read_stralloc (const char *filename) break; } - return bufstr; + return buffer; } +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 --------------090502070409060408090108-- From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28817 invoked by alias); 27 Mar 2013 20:17:57 -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 28355 invoked by uid 89); 27 Mar 2013 20:17:49 -0000 X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,FSL_HELO_BARE_IP_2,KHOP_THREADED,RCVD_IN_DNSWL_NONE,RCVD_NUMERIC_HELO,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_XS autolearn=no 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; Wed, 27 Mar 2013 20:17:46 +0000 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1UKwnP-0006Xe-MH for gdb-patches@sourceware.org; Wed, 27 Mar 2013 21:18:07 +0100 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 ; Wed, 27 Mar 2013 21:18:07 +0100 Received: from ARistovski by 209.226.137.106 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Wed, 27 Mar 2013 21:18:07 +0100 To: gdb-patches@sourceware.org From: Aleksandar Ristovski Subject: Re: [patch 4/6] Prepare linux_find_memory_regions_full & co. for move Date: Wed, 27 Mar 2013 21:54:00 -0000 Message-ID: <515353C4.2050203@qnx.com> References: <51278984.3070208@qnx.com> <20130310210820.GE21130@host2.jankratochvil.net> <514C56CB.4070207@qnx.com> <20130326165242.GA12291@host2.jankratochvil.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------090502070409060408090108" 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: <20130326165242.GA12291@host2.jankratochvil.net> X-Virus-Found: No X-SW-Source: 2013-03/txt/msg01041.txt.bz2 Message-ID: <20130327215400.T924sOT0O6KJzoOFrcq4NS613Yb-MDyltsbP1wQQYW8@z> This is a multi-part message in MIME format. --------------090502070409060408090108 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 240 New patch #4/6. Changed: read_stralloc is now refactored here, rather than in #5/6 where it gets moved, so that move remains clean in #5. Similarly, the change for linux_find_memory_regions_full moved from #5 here. Thanks, Aleksandar --------------090502070409060408090108 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: 12626 >From 8c30427ad466b50bdfe3e0e8cf9609545fcc3e4c Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Wed, 27 Mar 2013 09:49:36 -0400 Subject: [PATCH 4/6] 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 | 122 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 153 insertions(+), 66 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 9193c97..2195d0b 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3460,55 +3460,73 @@ 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) - xfree (buf); + if (n < 0 || (n == 0 && buf_pos == 0)) + { + if (memory_to_free_ptr != NULL) + { + gdb_assert (buf == *memory_to_free_ptr); + *memory_to_free_ptr = NULL; + } + xfree (buf); + } else *buf_p = buf; - return buf_pos; + + if (n < 0) + { + /* An error occurred. */ + return -1; + } + else + { + /* Read all there was. */ + return buf_pos; + } } buf_pos += n; @@ -3518,12 +3536,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. */ @@ -3540,15 +3580,16 @@ 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; + char *buffer; LONGEST i, transferred; - transferred = target_fileio_read_alloc_1 (filename, &buffer, 1); - bufstr = (char *) buffer; + transferred = func (filename, (gdb_byte **) &buffer, 1); if (transferred < 0) return NULL; @@ -3556,11 +3597,11 @@ target_fileio_read_stralloc (const char *filename) if (transferred == 0) return xstrdup (""); - bufstr[transferred] = 0; + buffer[transferred] = 0; /* Check for embedded NUL bytes; but allow trailing NULs. */ - for (i = strlen (bufstr); i < transferred; i++) - if (bufstr[i] != 0) + for (i = strlen (buffer); i < transferred; i++) + if (buffer[i] != 0) { warning (_("target file %s " "contained unexpected null characters"), @@ -3568,9 +3609,14 @@ target_fileio_read_stralloc (const char *filename) break; } - return bufstr; + return buffer; } +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 --------------090502070409060408090108--