From: David Gibson <david@gibson.dropbear.id.au>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: linuxppc-dev@ozlabs.org
Subject: Re: [LIBFDT] Fixup byteswapping code
Date: Mon, 4 Dec 2006 18:16:29 +1100 [thread overview]
Message-ID: <20061204071629.GC32026@localhost.localdomain> (raw)
In-Reply-To: <528646bc0612032233y573dfbcdk29a969e19540242a@mail.gmail.com>
On Sun, Dec 03, 2006 at 11:33:42PM -0700, Grant Likely wrote:
> On 12/3/06, David Gibson <david@gibson.dropbear.id.au> wrote:
> > On Sun, Dec 03, 2006 at 10:18:25PM -0700, Grant Likely wrote:
> > > This requires a hacky cast from int to pointer and back again, and it
> > > makes the assumption that int and void* are the same size. However,
> > > on a x86_64 system (not sure about power64), int is 32 bits and void*
> > > is 64. Therefore; a return of (void*)-1 results in address
> > > 0xffffffff; not 0xffffffffffffffff. 0xffffffff is right in the middle
> > > of valid address ranges.
> >
> > Urg. Yes indeed. The same is true on powerpc64, but userspace is
> > usually 32-bits on powerpc64 machines; I hadn't tested compiling
> > 64-bit. An extra (long) in PTR_ERROR() appears to be enough to fix
> > it.
> >
> > > This, of course, produces the warning: "cast to pointer from integer
> > > of different size"
> > >
> > > I believe the accepted convention (at least in the kernel) is to
> > > return NULL on error, and libfdt should probably follow that
> > > convention.
> >
> > Actually, there are two conventions in the kernel. Just returning
> > NULL on error is the most common. But there's a significant number of
> > functions that encode an errno into the returned pointer in just this
> > way - see the IS_ERR(), PTR_ERR() and ERR_PTR() macros.
>
> Ah, okay, I see that code now.
>
> Hmmm....
>
> Gah, this still makes me really nervous. The hard part will be how to
> make it *blatently* obvious to users that checking for NULL is *not*
> sufficient for error checking when using these functions. Otherwise a
> very common code defect will be code using just a NULL check before
> dereferencing the returned pointer.
Exactly. It makes me very nervous, too.
> > > If you must return the actual error code; maybe rework
> > > the API to accept a void** argument to be used to pass back the
> > > pointer and use 'return code', or include an 'int*' argument for
> > > passing back the err code.
> >
> > I thought quite a bit about how to pass back errors here. I'm not
> > very fond of the current method of encoding the error codes into the
> > return values - it's more magic than I'm comfortable with (especially
> > given the multiple encoding methods for different return types) - but
> > I haven't thought of a better way.
>
> heh; Isn't beating your head against the limits of a language fun? I
> wish I had a better suggestion myself, but I understand your point and
> the difficulty involved.
>
> > Having to use a void ** for the real return value is ugly - and means
> > you can't stack library calls together (result of one call as
> > parameter to another call). Using int * for the error code is also
> > ugly and all too much encouragement for people not too check it.
>
> Yeah, I agree 100%.
>
> > What I'd really prefer is an errno-style interface, where a separate
> > variable or call must be consulted to find the details of the error.
> > But, I can't see any way to do that safely in code that's supposed to
> > be easy to import into a wide variety of execution environments
> > (kernel, zImage, bootloader, userspace) - some of which could be
> > multithreaded.
>
> Unfortunately, there is no simple way to keep around execution
> context. newlib uses a scheme where the exec environment has to
> specifically tell it which thread context to use, but it's a bit ugly
> in that hooks must be added to the thread scheduler to change the
> context pointer on every schedule.
Sure, and if I set up something to use the newlib scheme, it would
break in things using a different approach.
> > Oh incidentally, this isn't true at present, but I'd like to make it
> > true: all the library functions should check their parameters so if
> > they're *given* one of the encoded error values, they'll just
> > propagate the error out again and won't do anything nasty. That will
> > make it safe to nest library calls, even if the inner ones could fail.
>
> good idea
I do have one idea for better error handling: I'd like to put in
something defined in the the libfdt_env.h (which is designed to be
replaced when libfdt is compiled in different environments) to report
an error. That would be invoked every time a libfdt function exits
with an error - I would envisage it calling through to a user supplied
function pointer.
In many practical situations, I think most libfdt errors would be the
result of something unrecoverable problem (such as a corrupted device
tree blob), the callback could just print an error (by whatever means
is appropritate for the environment) and bail out, avoiding the need
for checking return values. At least for the "serious" errors
(BADMAGIC, BADSTRUCTURE and so forth). NOTFOUND (and maybe TRUNCATED)
would need to be passed back as a return value still, since that can
certainly occur in a legitimate test.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
next prev parent reply other threads:[~2006-12-04 7:16 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-02 8:45 [LIBFDT] Fixup byteswapping code Grant Likely
2006-12-02 8:45 ` [LIBFDT] Add .dtb files to .gitignore Grant Likely
2006-12-02 9:30 ` Segher Boessenkool
2006-12-04 0:19 ` David Gibson
2006-12-04 1:53 ` [LIBFDT] Fixup byteswapping code David Gibson
2006-12-04 5:18 ` Grant Likely
2006-12-04 5:52 ` David Gibson
2006-12-04 6:33 ` Grant Likely
2006-12-04 7:16 ` David Gibson [this message]
2006-12-04 14:55 ` Grant Likely
2006-12-08 6:09 ` David Gibson
2006-12-15 4:15 ` David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061204071629.GC32026@localhost.localdomain \
--to=david@gibson.dropbear.id.au \
--cc=grant.likely@secretlab.ca \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).