Re: [PATCH v2 03/10] pylibfdt: Add support for the rest of the header functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hi David,

On 12 June 2018 at 21:31, David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> wrote:
> On Tue, Jun 12, 2018 at 09:04:21PM -0600, Simon Glass wrote:
>> Hi David,
>>
>> On 11 June 2018 at 22:42, David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> wrote:
>> > On Sat, Jun 09, 2018 at 11:12:44AM -0800, Simon Glass wrote:
>> >> Hi David,
>> >>
>> >> On 8 June 2018 at 04:27, David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> wrote:
>> >> > On Wed, Jun 06, 2018 at 03:37:02PM -0600, Simon Glass wrote:
>> >> >> Export all of these through Python.
>> >> >>
>> >> >> Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx>
>> >> >> ---
>> >> >>
>> >> >> Changes in v2:
>> >> >> - Drop use of check_err() since these functions cannot fail
>> >> >> - Update existing header functions to also drop check_err()
>> >> >>
>> >> >>  pylibfdt/libfdt.i       | 71 +++++++++++++++++++++++++++++++++++++++--
>> >> >>  tests/pylibfdt_tests.py |  8 +++++
>> >> >>  2 files changed, 76 insertions(+), 3 deletions(-)
>> >> >>
>> >> >> diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
>> >> >> index 94c3d00..f33e2ab 100644
>> >> >> --- a/pylibfdt/libfdt.i
>> >> >> +++ b/pylibfdt/libfdt.i
>> >> >> @@ -252,21 +252,86 @@ class Fdt:
>> >> >>          """
>> >> >>          return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet)
>> >> >>
>> >> >> +    def magic(self):
>> >> >> +        """Return the magic word from the header
>> >> >> +
>> >> >> +        Returns:
>> >> >> +            Magic word
>> >> >> +        """
>> >> >> +        # Use a mask to ensure that this does not return a -ve number
>> >> >> +        return fdt_magic(self._fdt) & 0xffffffff
>> >> >
>> >> > You still have the mask here for no clear reason.
>> >>
>> >> Python's numbers are a little strange. If the top bit of a 32-bit
>> >> number is set, this means it is a negative number in two-complement
>> >> arithmetic, as you know. Python will then use a negative value instead
>> >> of positive. To force it to regard the number as unsigned, we must
>> >> mask it. This is how I have learned to do it in Python, but maybe
>> >> there is a better way?
>> >
>> > Two observations first:
>> >
>> > 1) I'm pretty sure this will only apply on 32-bit platforms
>> > (specifically those where a C "long" and therefore a Python int() are
>> > 32-bit).
>> >
>> > 2) I think this has more to do with the swig typemapping that the
>> > integers in Python per se.  On a 32-bit platform I can do this in
>> > Python:
>> >     >>> (1 << 31)
>> >     2147483648L
>> >
>> > So we're getting the expected answer... but as a Python long rather
>> > than a Python int (it's a Python int when run on a 64-bit platform).
>> >
>> > So what seems to be happening here is that on the C side (not sure if
>> > it's in stuff you've written or in swig's generated magic), we're
>> > forcing the 'uint32_t' into a 'long', then stuffing that into a Python
>> > integer.
>> >
>> > The mask strips away the sign, and at the same time coerces the value
>> > into a Python long (because 0xffffffff will be a PyLong on such a
>> > platform).
>> >
>> >> To see the impact, try removing the mask. You will see that magic()
>> >> will return a -ve number, rather than unsigned.
>> >
>> > So, the thing that bothers me a bit here is that it's not the same for
>> > all the header functions, even though they all return uint32_t on the
>> > C side.  I guess we get away with in practice, because apart from
>> > 'magic' all the other values should actually fit in 31 bits.  Could
>> > still cause confusing answers on a malformed fdt, of course.
>> >
>> > I think the right solution is to alter the swig stuff so that on
>> > platforms where sizeof(long) <= 4 we make the header functions return
>> > a PyLong instead of a PyInt. I'm not immediately sure how to do that,
>> > however.
>> >
>> > I guess the current approach will work for now, even if it is a hack,
>> > so I'll go ahead and apply it, and we can try to fix it up later.
>>
>> Thanks for digging into this. Yes this is definitely a typemap thing
>> and I think I have a culprit.
>>
>> The #defines in libfdt.h are actually not used with swig, since it
>> doesn't support that. Instead I am re-declaring these functions, and
>> when I do so, they are declared as int. They should be fdt32_t to
>> match the struct member types.
>
> Actually, they should be uint32_t.  fdt32_t specifically refers to a
> 32-bit integer *in big endian representation.

Ah OK, I suppose I knew that. But I think that may the inspiration for
my error - just looking at the header struct and assuming that the
macros returns the same type.

>
>> On top of that the fdt32_t type in the header is declared as int. This
>> type has so far only been used for struct members, e.g. struct
>> fdt_property so it didn't matter. But really it should be uint32_t to
>> match the libfdt.h header.
>
> Yes, that needs fixing.
>
>> That would make everything consistent I think. A quick test suggests
>> it solves the problem although I need to convince myself that other
>> changes aren't also needed. After that I'll send a patch to modify all
>> of those.
>
> Great.

Regards,
Simon
--
To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux