From patchwork Sat Mar 22 11:18:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 234 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx21.g.dreamhost.com (caibbdcaaahb.dreamhost.com [208.113.200.71]) by wilcox.dreamhost.com (Postfix) with ESMTP id 76A80360080 for ; Sat, 22 Mar 2014 04:20:53 -0700 (PDT) Received: by homiemail-mx21.g.dreamhost.com (Postfix, from userid 14314964) id 121D2C98439; Sat, 22 Mar 2014 04:20:52 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx21.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx21.g.dreamhost.com (Postfix) with ESMTPS id C5FFDC86E21 for ; Sat, 22 Mar 2014 04:20:52 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:cc :subject:references:in-reply-to:content-type :content-transfer-encoding; q=dns; s=default; b=A3abyoqibs9Z+AdV pSfR1uFZmxq9Vq/anlFF2cxG7ZRzxh2KCH1YAZhqF8tJYD6ZDEdT6llrRG58rniB 179TNqebGD9QzLrAwQ1OJyvJvD9XrPPhPIEZpibyUJVa/cBaY+700teaWHhEnFz1 1EhR+XSbQEj8aWTyQ69bxjUHuUc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:cc :subject:references:in-reply-to:content-type :content-transfer-encoding; s=default; bh=AFnKNdlG5OOglnP4rggTN8 I3PDI=; b=EaU8HnNgaw7nuyfoj3eAMScjsyA/CKTnOKGmEH9B0HgIJwEIZzOyBj BVZrMRqGKROVz59+nO3H7SFDoMptSPEsW6B5IC9EXjY/kUIqwfjhfRzbtF6XPcQe gAjfi+dyYZDDg+4xZy+2UQqVWNXMaPHKrSyM2T1erCoIxmOqmuZos= Received: (qmail 14222 invoked by alias); 22 Mar 2014 11:20:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 14208 invoked by uid 89); 22 Mar 2014 11:20:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 22 Mar 2014 11:20:47 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1WRJyk-0001z3-Jn from Yao_Qi@mentor.com ; Sat, 22 Mar 2014 04:20:42 -0700 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Sat, 22 Mar 2014 04:20:42 -0700 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.2.247.3; Sat, 22 Mar 2014 04:20:41 -0700 Message-ID: <532D717C.5010504@codesourcery.com> Date: Sat, 22 Mar 2014 19:18:20 +0800 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130110 Thunderbird/17.0.2 MIME-Version: 1.0 To: Pedro Alves CC: Subject: Re: [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets References: <1394541731-27486-1-git-send-email-yao@codesourcery.com> <532C28F1.5040705@redhat.com> In-Reply-To: <532C28F1.5040705@redhat.com> X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in On 03/21/2014 07:56 PM, Pedro Alves wrote: > This "&remote_ops" here will be wrong in case we're connected > with extended-remote. Looks like remote_read_bytes needs to be > gain an ops parameter. Right, add 'ops' argument to remote_read_bytes in the updated patch. Patch below is pushed in. diff --git a/gdb/ctf.c b/gdb/ctf.c index 95fd31f..ebd40d6 100644 --- a/gdb/ctf.c +++ b/gdb/ctf.c @@ -1377,6 +1377,7 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, { struct bt_iter_pos *pos; int i = 0; + enum target_xfer_status res; gdb_assert (ctf_iter != NULL); /* Save the current position. */ @@ -1466,7 +1467,20 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, /* Restore the position. */ bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); - return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + /* Requested memory is unavailable in the context of traceframes, + and this address falls within a read-only section, fallback + to reading from executable. */ + res = exec_read_partial_read_only (readbuf, offset, len, xfered_len); + + if (res == TARGET_XFER_OK) + return TARGET_XFER_OK; + else + { + /* No use trying further, we know some memory starting + at MEMADDR isn't available. */ + *xfered_len = len; + return TARGET_XFER_UNAVAILABLE; + } } else { diff --git a/gdb/remote.c b/gdb/remote.c index e03d3bf..dcee6e1 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6824,6 +6824,87 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len, packet_format[0], 1); } +/* Read memory from the live target, even if currently inspecting a + traceframe. The return is the same as that of target_read. */ + +static enum target_xfer_status +target_read_live_memory (enum target_object object, + ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len, + ULONGEST *xfered_len) +{ + enum target_xfer_status ret; + struct cleanup *cleanup; + + /* Switch momentarily out of tfind mode so to access live memory. + Note that this must not clear global state, such as the frame + cache, which must still remain valid for the previous traceframe. + We may be _building_ the frame cache at this point. */ + cleanup = make_cleanup_restore_traceframe_number (); + set_traceframe_number (-1); + + ret = target_xfer_partial (current_target.beneath, object, NULL, + myaddr, NULL, memaddr, len, xfered_len); + + do_cleanups (cleanup); + return ret; +} + +/* Using the set of read-only target sections of OPS, read live + read-only memory. Note that the actual reads start from the + top-most target again. + + For interface/parameters/return description see target.h, + to_xfer_partial. */ + +static enum target_xfer_status +memory_xfer_live_readonly_partial (struct target_ops *ops, + enum target_object object, + gdb_byte *readbuf, ULONGEST memaddr, + ULONGEST len, ULONGEST *xfered_len) +{ + struct target_section *secp; + struct target_section_table *table; + + secp = target_section_by_addr (ops, memaddr); + if (secp != NULL + && (bfd_get_section_flags (secp->the_bfd_section->owner, + secp->the_bfd_section) + & SEC_READONLY)) + { + struct target_section *p; + ULONGEST memend = memaddr + len; + + table = target_get_section_table (ops); + + for (p = table->sections; p < table->sections_end; p++) + { + if (memaddr >= p->addr) + { + if (memend <= p->endaddr) + { + /* Entire transfer is within this section. */ + return target_read_live_memory (object, memaddr, + readbuf, len, xfered_len); + } + else if (memaddr >= p->endaddr) + { + /* This section ends before the transfer starts. */ + continue; + } + else + { + /* This section overlaps the transfer. Just do half. */ + len = p->endaddr - memaddr; + return target_read_live_memory (object, memaddr, + readbuf, len, xfered_len); + } + } + } + } + + return TARGET_XFER_EOF; +} + /* Read memory data directly from the remote machine. This does not use the data cache; the data cache uses this. MEMADDR is the address in the remote memory space. @@ -6835,8 +6916,8 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len, transferred in *XFERED_LEN. */ static enum target_xfer_status -remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, - ULONGEST *xfered_len) +remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, + gdb_byte *myaddr, ULONGEST len, ULONGEST *xfered_len) { struct remote_state *rs = get_remote_state (); int max_buf_size; /* Max size of packet output buffer. */ @@ -6847,6 +6928,63 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, if (len == 0) return 0; + if (get_traceframe_number () != -1) + { + VEC(mem_range_s) *available; + + /* If we fail to get the set of available memory, then the + target does not support querying traceframe info, and so we + attempt reading from the traceframe anyway (assuming the + target implements the old QTro packet then). */ + if (traceframe_available_memory (&available, memaddr, len)) + { + struct cleanup *old_chain; + + old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); + + if (VEC_empty (mem_range_s, available) + || VEC_index (mem_range_s, available, 0)->start != memaddr) + { + enum target_xfer_status res; + + /* Don't read into the traceframe's available + memory. */ + if (!VEC_empty (mem_range_s, available)) + { + LONGEST oldlen = len; + + len = VEC_index (mem_range_s, available, 0)->start - memaddr; + gdb_assert (len <= oldlen); + } + + do_cleanups (old_chain); + + /* This goes through the topmost target again. */ + res = memory_xfer_live_readonly_partial (ops, + TARGET_OBJECT_MEMORY, + myaddr, memaddr, + len, xfered_len); + if (res == TARGET_XFER_OK) + return TARGET_XFER_OK; + else + { + /* No use trying further, we know some memory starting + at MEMADDR isn't available. */ + *xfered_len = len; + return TARGET_XFER_UNAVAILABLE; + } + } + + /* Don't try to read more than how much is available, in + case the target implements the deprecated QTro packet to + cater for older GDBs (the target's knowledge of read-only + sections may be outdated by now). */ + len = VEC_index (mem_range_s, available, 0)->length; + + do_cleanups (old_chain); + } + } + max_buf_size = get_memory_read_packet_size (); /* The packet buffer will be large enough for the payload; get_memory_packet_size ensures this. */ @@ -8698,7 +8836,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, if (writebuf != NULL) return remote_write_bytes (offset, writebuf, len, xfered_len); else - return remote_read_bytes (offset, readbuf, len, xfered_len); + return remote_read_bytes (ops, offset, readbuf, len, xfered_len); } /* Handle SPU memory using qxfer packets. */ diff --git a/gdb/target.c b/gdb/target.c index 0d22297..1b48f79 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -940,87 +940,6 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr) return NULL; } -/* Read memory from the live target, even if currently inspecting a - traceframe. The return is the same as that of target_read. */ - -static enum target_xfer_status -target_read_live_memory (enum target_object object, - ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len, - ULONGEST *xfered_len) -{ - enum target_xfer_status ret; - struct cleanup *cleanup; - - /* Switch momentarily out of tfind mode so to access live memory. - Note that this must not clear global state, such as the frame - cache, which must still remain valid for the previous traceframe. - We may be _building_ the frame cache at this point. */ - cleanup = make_cleanup_restore_traceframe_number (); - set_traceframe_number (-1); - - ret = target_xfer_partial (current_target.beneath, object, NULL, - myaddr, NULL, memaddr, len, xfered_len); - - do_cleanups (cleanup); - return ret; -} - -/* Using the set of read-only target sections of OPS, read live - read-only memory. Note that the actual reads start from the - top-most target again. - - For interface/parameters/return description see target.h, - to_xfer_partial. */ - -static enum target_xfer_status -memory_xfer_live_readonly_partial (struct target_ops *ops, - enum target_object object, - gdb_byte *readbuf, ULONGEST memaddr, - ULONGEST len, ULONGEST *xfered_len) -{ - struct target_section *secp; - struct target_section_table *table; - - secp = target_section_by_addr (ops, memaddr); - if (secp != NULL - && (bfd_get_section_flags (secp->the_bfd_section->owner, - secp->the_bfd_section) - & SEC_READONLY)) - { - struct target_section *p; - ULONGEST memend = memaddr + len; - - table = target_get_section_table (ops); - - for (p = table->sections; p < table->sections_end; p++) - { - if (memaddr >= p->addr) - { - if (memend <= p->endaddr) - { - /* Entire transfer is within this section. */ - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); - } - else if (memaddr >= p->endaddr) - { - /* This section ends before the transfer starts. */ - continue; - } - else - { - /* This section overlaps the transfer. Just do half. */ - len = p->endaddr - memaddr; - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); - } - } - } - } - - return TARGET_XFER_EOF; -} - /* Read memory from more than one valid target. A core file, for instance, could have some of memory but delegate other bits to the target below it. So, we must manually try all targets. */ @@ -1128,63 +1047,6 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, } } - /* If reading unavailable memory in the context of traceframes, and - this address falls within a read-only section, fallback to - reading from live memory. */ - if (readbuf != NULL && get_traceframe_number () != -1) - { - VEC(mem_range_s) *available; - - /* If we fail to get the set of available memory, then the - target does not support querying traceframe info, and so we - attempt reading from the traceframe anyway (assuming the - target implements the old QTro packet then). */ - if (traceframe_available_memory (&available, memaddr, len)) - { - struct cleanup *old_chain; - - old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); - - if (VEC_empty (mem_range_s, available) - || VEC_index (mem_range_s, available, 0)->start != memaddr) - { - /* Don't read into the traceframe's available - memory. */ - if (!VEC_empty (mem_range_s, available)) - { - LONGEST oldlen = len; - - len = VEC_index (mem_range_s, available, 0)->start - memaddr; - gdb_assert (len <= oldlen); - } - - do_cleanups (old_chain); - - /* This goes through the topmost target again. */ - res = memory_xfer_live_readonly_partial (ops, object, - readbuf, memaddr, - len, xfered_len); - if (res == TARGET_XFER_OK) - return TARGET_XFER_OK; - else - { - /* No use trying further, we know some memory starting - at MEMADDR isn't available. */ - *xfered_len = len; - return TARGET_XFER_UNAVAILABLE; - } - } - - /* Don't try to read more than how much is available, in - case the target implements the deprecated QTro packet to - cater for older GDBs (the target's knowledge of read-only - sections may be outdated by now). */ - len = VEC_index (mem_range_s, available, 0)->length; - - do_cleanups (old_chain); - } - } - /* Try GDB's internal data cache. */ region = lookup_mem_region (memaddr); /* region->hi == 0 means there's no upper bound. */ diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c index cbf746d..a36596f 100644 --- a/gdb/tracefile-tfile.c +++ b/gdb/tracefile-tfile.c @@ -900,6 +900,7 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object, if (get_traceframe_number () != -1) { int pos = 0; + enum target_xfer_status res; /* Iterate through the traceframe's blocks, looking for memory. */ @@ -937,7 +938,20 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object, pos += (8 + 2 + mlen); } - return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + /* Requested memory is unavailable in the context of traceframes, + and this address falls within a read-only section, fallback + to reading from executable. */ + res = exec_read_partial_read_only (readbuf, offset, len, xfered_len); + + if (res == TARGET_XFER_OK) + return TARGET_XFER_OK; + else + { + /* No use trying further, we know some memory starting + at MEMADDR isn't available. */ + *xfered_len = len; + return TARGET_XFER_UNAVAILABLE; + } } else {