From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7188 invoked by alias); 16 Apr 2013 15:45:31 -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 7162 invoked by uid 89); 16 Apr 2013 15:45:31 -0000 X-Spam-SWARE-Status: No, score=-4.6 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 na3sys009aog122.obsmtp.com (HELO na3sys009aog122.obsmtp.com) (74.125.149.147) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 16 Apr 2013 15:45:30 +0000 Received: from mx20.qnx.com ([72.1.200.103]) (using TLSv1) by na3sys009aob122.postini.com ([74.125.148.12]) with SMTP ID DSNKUW1yFcqKtVDB3WxWGIkd73xJoebJuxET@postini.com; Tue, 16 Apr 2013 08:45:29 PDT Received: by mx20.qnx.com (Postfix, from userid 500) id 2C5B921129; Tue, 16 Apr 2013 11:45:23 -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 mx20.qnx.com (Postfix) with ESMTPS id 6F4292110D; Tue, 16 Apr 2013 11:45:22 -0400 (EDT) Received: from qnxws8996.ott.qnx.com (10.222.2.5) by EXCH1.ott.qnx.com (10.222.2.137) with Microsoft SMTP Server id 14.2.318.4; Tue, 16 Apr 2013 11:45:22 -0400 From: Aleksandar Ristovski To: CC: , Aleksandar Ristovski Subject: [PATCH 4/8] Prepare linux_find_memory_regions_full & co. for move Date: Tue, 16 Apr 2013 18:31:00 -0000 Message-ID: <1366127096-5744-5-git-send-email-ARistovski@qnx.com> In-Reply-To: <1366127096-5744-1-git-send-email-ARistovski@qnx.com> References: <1365521265-28870-1-git-send-email-ARistovski@qnx.com> <1366127096-5744-1-git-send-email-ARistovski@qnx.com> MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2013-04/txt/msg00488.txt.bz2 * 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 (read_alloc_pread_ftype): New typedef. (target_fileio_read_alloc_1_pread): New function. (read_alloc): Refactor from target_fileio_read_alloc_1. (read_stralloc_func_ftype): New typedef. (target_fileio_read_alloc_1): New implementation. Use read_alloc. (read_stralloc): Refactored from target_fileio_read_stralloc. (target_fileio_read_stralloc): New implementation, use read_stralloc. --- gdb/linux-tdep.c | 98 +++++++++++++++++++++++++++++++++++--------------- gdb/target.c | 106 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 146 insertions(+), 58 deletions(-) diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 9def108..77c98d2 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,41 @@ 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 mapsfilename[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 (mapsfilename, sizeof mapsfilename, - "/proc/%d/smaps", current_inferior ()->pid); + xsnprintf (mapsfilename, sizeof mapsfilename, "/proc/%d/smaps", (int) pid); data = target_fileio_read_stralloc (mapsfilename); if (data == NULL) { /* Older Linux kernels did not support /proc/PID/smaps. */ - xsnprintf (mapsfilename, sizeof mapsfilename, - "/proc/%d/maps", current_inferior ()->pid); + xsnprintf (mapsfilename, sizeof mapsfilename, "/proc/%d/maps", + (int) pid); data = target_fileio_read_stralloc (mapsfilename); } 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) @@ -752,15 +763,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 @@ -774,9 +792,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. */ @@ -788,7 +808,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 @@ -796,16 +839,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. */ @@ -987,8 +1029,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 8f8e46a..33afe2b 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3476,6 +3476,22 @@ target_fileio_close_cleanup (void *opaque) target_fileio_close (fd, &target_errno); } +typedef int (read_alloc_pread_ftype) (int handle, gdb_byte *read_buf, int len, + ULONGEST offset, int *target_errno); + +static read_alloc_pread_ftype target_fileio_read_alloc_1_pread; + +/* 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 @@ -3483,48 +3499,46 @@ target_fileio_close_cleanup (void *opaque) information. */ 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 +3548,39 @@ 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; } } +typedef LONGEST (read_stralloc_func_ftype) (const char *filename, + gdb_byte **buf_p, int padding); + +static read_stralloc_func_ftype target_fileio_read_alloc_1; + +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 +3597,14 @@ 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) +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 +3628,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