From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26946 invoked by alias); 25 Feb 2014 17:31:50 -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 26935 invoked by uid 89); 25 Feb 2014 17:31:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 25 Feb 2014 17:31:48 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s1PHVjhs025639 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 25 Feb 2014 12:31:45 -0500 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s1PHVhvb021431; Tue, 25 Feb 2014 12:31:44 -0500 Message-ID: <530CD37F.3050106@redhat.com> Date: Tue, 25 Feb 2014 17:31:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 To: Joel Brobecker CC: gdb-patches@sourceware.org Subject: Re: [commit] Adjust ia64_linux_xfer_partial following to_xfer_partial API change. References: <1393345450-20878-1-git-send-email-brobecker@adacore.com> In-Reply-To: <1393345450-20878-1-git-send-email-brobecker@adacore.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-SW-Source: 2014-02/txt/msg00754.txt.bz2 On 02/25/2014 04:24 PM, Joel Brobecker wrote: > + if (object == TARGET_OBJECT_UNWIND_TABLE && readbuf != NULL) > + { > + gdb_byte *tmp_buf = alloca (offset + len); > + ULONGEST xfered; > + > + xfered = syscall (__NR_getunwind, readbuf, offset + len); It seems this should have passed tmp_buf instead of readbuf? Also, I don't think the "offset + len" size is the right size to pass down to the syscall. From: http://lxr.free-electrons.com/source/arch/ia64/kernel/unwind.c#L2313 2291 * This system call copies the unwind data into the buffer pointed to by BUF and returns 2292 * the size of the unwind data. If BUF_SIZE is smaller than the size of the unwind data 2293 * or if BUF is NULL, nothing is copied, but the system call still returns the size of the 2294 * unwind data. So it looks like this code is getting lucky and the caller is requesting enough bytes: x = target_read_alloc (¤t_target, TARGET_OBJECT_UNWIND_TABLE, NULL, buf_p); But to_xfer_partial implementations should not assume that. E.g., change target_read_alloc_1 to start by requesting a byte at a time instead of 4096, and this will fail. > + if (xfered <= 0) Note that because xfered is ULONGEST, this won't actually detect errors. > + return TARGET_XFER_E_IO; > + else if (xfered <= offset) Not sure I follow this one. > + return TARGET_XFER_EOF; > + else > + { > + memcpy (readbuf, tmp_buf + offset, xfered - offset); > + *xfered_len = xfered - offset; > + return TARGET_XFER_OK; > + } > + } I suggest something along the lines of the below instead. Should handle partial requests, and clearer to read, I think. Completely untested, though. --- gdb/ia64-linux-nat.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c index c057b55..65a57d2 100644 --- a/gdb/ia64-linux-nat.c +++ b/gdb/ia64-linux-nat.c @@ -850,20 +850,30 @@ ia64_linux_xfer_partial (struct target_ops *ops, { if (object == TARGET_OBJECT_UNWIND_TABLE && readbuf != NULL) { - gdb_byte *tmp_buf = alloca (offset + len); - ULONGEST xfered; + static long gate_table_size; + gdb_byte *tmp_buf; + long res; - xfered = syscall (__NR_getunwind, readbuf, offset + len); - if (xfered <= 0) - return TARGET_XFER_E_IO; - else if (xfered <= offset) + /* Probe for the table size once. */ + if (gate_table_size == 0) + gate_table_size = syscall (__NR_getunwind, NULL, 0); + if (gate_table_size < 0) + return TARGET_XFER_EIO; + + if (offset >= gate_table_size) return TARGET_XFER_EOF; - else - { - memcpy (readbuf, tmp_buf + offset, xfered - offset); - *xfered_len = xfered - offset; - return TARGET_XFER_OK; - } + + tmp_buf = alloca (gate_table_size); + if (syscall (__NR_getunwind, tmp_buf, gate_table_size) < 0) + return TARGET_XFER_EIO; + gdb_assert (res == gate_table_size); + + if (offset + len > gate_table_size) + len = gate_table_size - offset; + + memcpy (readbuf, tmp_buf + offset, len); + *xfered_len = len; + return TARGET_XFER_OK; } return super_xfer_partial (ops, object, annex, readbuf, writebuf, -- 1.7.11.7