From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16237 invoked by alias); 26 Jul 2006 21:53:39 -0000 Received: (qmail 16137 invoked by uid 22791); 26 Jul 2006 21:53:30 -0000 X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO sibelius.xs4all.nl) (82.92.89.47) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 26 Jul 2006 21:53:22 +0000 Received: from elgar.sibelius.xs4all.nl (root@elgar.sibelius.xs4all.nl [192.168.0.2]) by sibelius.xs4all.nl (8.13.4/8.13.4) with ESMTP id k6QLpQtU020723; Wed, 26 Jul 2006 23:51:26 +0200 (CEST) Received: from elgar.sibelius.xs4all.nl (kettenis@localhost.sibelius.xs4all.nl [127.0.0.1]) by elgar.sibelius.xs4all.nl (8.13.6/8.13.6) with ESMTP id k6QLpPqw012043; Wed, 26 Jul 2006 23:51:25 +0200 (CEST) Received: (from kettenis@localhost) by elgar.sibelius.xs4all.nl (8.13.6/8.13.6/Submit) id k6QLpOLX018719; Wed, 26 Jul 2006 23:51:24 +0200 (CEST) Date: Wed, 26 Jul 2006 21:53:00 -0000 Message-Id: <200607262151.k6QLpOLX018719@elgar.sibelius.xs4all.nl> From: Mark Kettenis To: drow@false.org CC: vladimir@codesourcery.com, gdb-patches@sources.redhat.com In-reply-to: <20060724220043.GB18918@nevyn.them.org> (message from Daniel Jacobowitz on Mon, 24 Jul 2006 18:00:43 -0400) Subject: Re: [PATCH] zero-terminate result of target_read_alloc References: <200607181356.16071.vladimir@codesourcery.com> <24758.192.87.1.22.1153221922.squirrel@webmail.xs4all.nl> <20060724040937.GA24339@nevyn.them.org> <200607242138.k6OLcP7h023940@elgar.sibelius.xs4all.nl> <20060724220043.GB18918@nevyn.them.org> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00391.txt.bz2 > Date: Mon, 24 Jul 2006 18:00:43 -0400 > From: Daniel Jacobowitz > > All right! Compromise and progress! Thanks, Mark. > > How about this patch (untested so far)? My only concern is that it > doesn't report error/unsupported separately from empty; but for all the > uses I know of so far, that's not a problem, and we can change it later > if we need to. Better get this right from the start, and return xstrdup("") for "empty". Also the error message "... contained unexpected zero bytes" is not very clear; the first time I thought that would warn about returning an empty string. How about changing that to "... contained unexpected null characters" ? The C standard uses the term "null character" for a byte with all bits set to 0. > 2006-07-24 Daniel Jacobowitz > > * target.h (target_read_stralloc): New prototype. > * target.c (target_read_alloc_1): Renamed from target_read_alloc. > Take new PADDING argument. > (target_read_alloc): Use it. > (target_read_stralloc): New function. > > Index: target.h > =================================================================== > RCS file: /cvs/src/src/gdb/target.h,v > retrieving revision 1.85 > diff -u -p -r1.85 target.h > --- target.h 12 Jul 2006 18:13:45 -0000 1.85 > +++ target.h 24 Jul 2006 21:59:03 -0000 > @@ -236,6 +236,14 @@ extern LONGEST target_read_alloc (struct > enum target_object object, > const char *annex, gdb_byte **buf_p); > > +/* Read OBJECT/ANNEX using OPS. The result is NUL-terminated > + and returned as a string. A warning is issued if the result > + contains any embedded NUL bytes. */ > + > +extern char *target_read_stralloc (struct target_ops *ops, > + enum target_object object, > + const char *annex); > + > /* Wrappers to target read/write that perform memory transfers. They > throw an error if the memory transfer fails. > > Index: target.c > =================================================================== > RCS file: /cvs/src/src/gdb/target.c,v > retrieving revision 1.121 > diff -u -p -r1.121 target.c > --- target.c 18 Jul 2006 12:44:48 -0000 1.121 > +++ target.c 24 Jul 2006 21:59:03 -0000 > @@ -1406,22 +1406,15 @@ target_write (struct target_ops *ops, > return len; > } > > -/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will > - be read using OPS. The return value will be -1 if the transfer > - fails or is not supported; 0 if the object is empty; or the length > - of the object otherwise. If a positive value is returned, a > - sufficiently large buffer will be allocated using xmalloc and > - returned in *BUF_P containing the contents of the object. > - > - This method should be used for objects sufficiently small to store > - in a single xmalloc'd buffer, when no fixed bound on the object's > - size is known in advance. Don't try to read TARGET_OBJECT_MEMORY > - through this function. */ > - > -LONGEST > -target_read_alloc (struct target_ops *ops, > - enum target_object object, > - const char *annex, gdb_byte **buf_p) > +/* Read OBJECT/ANNEX using OPS. 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_read_alloc; see the declaration of that function for more > + information. */ > + > +static LONGEST > +target_read_alloc_1 (struct target_ops *ops, enum target_object object, > + const char *annex, gdb_byte **buf_p, int padding) > { > size_t buf_alloc, buf_pos; > gdb_byte *buf; > @@ -1442,7 +1435,7 @@ target_read_alloc (struct target_ops *op > while (1) > { > n = target_read_partial (ops, object, annex, &buf[buf_pos], > - buf_pos, buf_alloc - buf_pos); > + buf_pos, buf_alloc - buf_pos - padding); > if (n < 0) > { > /* An error occurred. */ > @@ -1472,6 +1465,41 @@ target_read_alloc (struct target_ops *op > } > } > > +/* Read OBJECT/ANNEX using OPS. 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. */ > + > +LONGEST > +target_read_alloc (struct target_ops *ops, enum target_object object, > + const char *annex, gdb_byte **buf_p) > +{ > + return target_read_alloc_1 (ops, object, annex, buf_p, 0); > +} > + > +/* Read OBJECT/ANNEX using OPS. The result is NUL-terminated > + and returned as a string. A warning is issued if the result > + contains any embedded NUL bytes. */ > + > +char * > +target_read_stralloc (struct target_ops *ops, enum target_object object, > + const char *annex) > +{ > + gdb_byte *buffer; > + LONGEST transferred; > + > + transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1); > + > + if (transferred <= 0) > + return NULL; > + > + buffer[transferred] = 0; > + if (strlen (buffer) < transferred) > + warning (_("target object %d, annex %s, contained unexpected zero bytes"), > + (int) object, annex ? annex : "(none)"); > + > + return (char *) buffer; > +} > + > /* Memory transfer methods. */ > > void >