All of lore.kernel.org
 help / color / mirror / Atom feed
* need help: cdrkit & bitifields
@ 2009-03-05 17:21 Frans Meulenbroeks
  2009-03-05 18:26 ` Koen Kooi
  0 siblings, 1 reply; 7+ messages in thread
From: Frans Meulenbroeks @ 2009-03-05 17:21 UTC (permalink / raw)
  To: openembedded-devel

[-- Attachment #1: Type: text/plain, Size: 1245 bytes --]

Hi,

I'm trying to make a package for cdrkit (recipe attached), but I am
kind a stuck.
The ported version does communicate to an USB DVD writer, but does not
recognize the type, whereas the same drive is recognized under
opensuse.

The data I get from the inquiry command ( wodim -inq -v -V ) is
initially the same but the result of inquiry is interpreted
differently.

I've tracked it down to the following:
in ./include/usal/scsireg.h it says:

struct  scsi_inquiry {
        Ucbit   type            : 5;    /*  0 */
        Ucbit   qualifier       : 3;    /*  0 */

        Ucbit   type_modifier   : 7;    /*  1 */
        Ucbit   removable       : 1;    /*  1 */

        Ucbit   ansi_version    : 3;    /*  2 */
        Ucbit   ecma_version    : 3;    /*  2 */
...
Ucbit is an unsigned char

In wodim/scsi_cdr.c function getdev a pointer is made to the data that
are read from the drive:
        register struct scsi_inquiry *inq = usalp->inq;

The type is in the first byte, which for my drive is 0x05
on opensuse this gives a type of 0x5, and a qualifier of 0 and on my
beagleboard it gives a type of 0 and a qualifier of 5.
Apparently bitfields are orderd differently.
How can this be fixed?

Frans

[-- Attachment #2: cdrkit_1.1.9.bb --]
[-- Type: application/octet-stream, Size: 343 bytes --]

# cdrkit build file

LICENSE="GPLv2"
DESCRIPTION="A set of tools for CD recording"
HOMEPAGE="http://www.cdrkit.org"

PARALLEL_MAKE = ""
DEPENDS = "libcap"
SRC_URI="http://cdrkit.org/releases/cdrkit-${PV}.tar.gz"

S="${WORKDIR}/cdrkit-${PV}"
PR = "r1"

do_install() {
	oe_runmake install DESTDIR="${D}"
	mv ${D}/usr/local/* ${D}${prefix}/ -f
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: need help: cdrkit & bitifields
  2009-03-05 17:21 need help: cdrkit & bitifields Frans Meulenbroeks
@ 2009-03-05 18:26 ` Koen Kooi
  2009-03-05 21:10   ` Frans Meulenbroeks
  0 siblings, 1 reply; 7+ messages in thread
From: Koen Kooi @ 2009-03-05 18:26 UTC (permalink / raw)
  To: openembedded-devel

On 05-03-09 18:21, Frans Meulenbroeks wrote:

> Ucbit is an unsigned char

unsigned char makes me think of 
http://www.arm.linux.org.uk/docs/faqs/signedchar.php

regards,

Koen




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: need help: cdrkit & bitifields
  2009-03-05 18:26 ` Koen Kooi
@ 2009-03-05 21:10   ` Frans Meulenbroeks
  2009-03-06  9:03     ` Phil Blundell
  2009-03-07  9:37     ` Khem Raj
  0 siblings, 2 replies; 7+ messages in thread
From: Frans Meulenbroeks @ 2009-03-05 21:10 UTC (permalink / raw)
  To: openembedded-devel

2009/3/5 Koen Kooi <k.kooi@student.utwente.nl>:
> On 05-03-09 18:21, Frans Meulenbroeks wrote:
>
>> Ucbit is an unsigned char
>
> unsigned char makes me think of
> http://www.arm.linux.org.uk/docs/faqs/signedchar.php
>
> regards,
>
> Koen

Well it is explictly defined as unsigned char.
from utypes.h:

/*
 * The IBM AIX C-compiler seems to be the only compiler on the world
 * which does not allow to use unsigned char bit fields as a hint
 * for packed bit fields. Define a pesical type to avoid warnings.
 * The packed attribute is honored wit unsigned int in this case too.
 */
#if     defined(_AIX) && !defined(__GNUC__)

typedef unsigned int    Ucbit;

#else

typedef unsigned char   Ucbit;

#endif

The link you give is related to chars that are by default signed or unsigned

This one seems to be related to whether bitfields are ordered left to
right or right to left
(and if I recall correctly in the ansi C standard this is undefined
(but it has been a while since I checked)

Decided to do some testing. On x86: gcc 4.3.2:
frans@linux-suse:~/wt> cat tst.c
#include <stdio.h>

typedef struct {
    unsigned char bit0:1;
    unsigned char bits:6;
    unsigned char bit7:1;
} bitfields;

main(int argc, char **argv)
{
    char c = 0xf0;
    bitfields *bf = &c;

    printf("bit 0 = %d, bits = %x, bit7 = %x\n", bf->bit0, bf->bits, bf->bit7);
}
frans@linux-suse:~/wt> gcc  tst.c
tst.c: In function ‘main’:
tst.c:12: warning: initialization from incompatible pointer type
frans@linux-suse:~/wt> ./a.out
bit 0 = 0, bits = 38, bit7 = 1
frans@linux-suse:~/wt> gcc -O1 tst.c
tst.c: In function ‘main’:
tst.c:12: warning: initialization from incompatible pointer type
frans@linux-suse:~/wt> ./a.out
bit 0 = 0, bits = 38, bit7 = 1
frans@linux-suse:~/wt> gcc -O2 tst.c
tst.c: In function ‘main’:
tst.c:12: warning: initialization from incompatible pointer type
frans@linux-suse:~/wt> ./a.out
bit 0 = 0, bits = 1c, bit7 = 1
frans@linux-suse:~/wt> gcc -O3 tst.c
tst.c: In function ‘main’:
tst.c:12: warning: initialization from incompatible pointer type
frans@linux-suse:~/wt> ./a.out
bit 0 = 0, bits = 1c, bit7 = 1

Same test on beagle (gcc 4.3.1), -O0  -O1 -O2 -O3
root@beagleboard:~# ./tst0
bit 0 = 0, bits = 38, bit7 = 1
root@beagleboard:~# ./tst1
bit 0 = 0, bits = 38, bit7 = 1
root@beagleboard:~# ./tst2
bit 0 = 0, bits = 20, bit7 = 0
root@beagleboard:~# ./tst3
bit 0 = 0, bits = 20, bit7 = 0

Not sure what is happening here.
I tried to compile cdrkit with -O1 using
FULL_OPTIMIZATION = "-O1"
FULL_OPTIMIZATION_armv7a = "-O1"
BUILD_OPTIMIZATION = "${FULL_OPTIMIZATION}"
but that did not help either.

There is a compile time macro in gcc called BITS_BIG_ENDIAN but that
one is set to 0 for arm (same as for x86).

Puzzled....

Frans



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: need help: cdrkit & bitifields
  2009-03-05 21:10   ` Frans Meulenbroeks
@ 2009-03-06  9:03     ` Phil Blundell
  2009-03-06  9:42       ` Frans Meulenbroeks
  2009-03-07  9:37     ` Khem Raj
  1 sibling, 1 reply; 7+ messages in thread
From: Phil Blundell @ 2009-03-06  9:03 UTC (permalink / raw)
  To: openembedded-devel

On Thu, 2009-03-05 at 22:10 +0100, Frans Meulenbroeks wrote:
> main(int argc, char **argv)
> {
>     char c = 0xf0;
>     bitfields *bf = &c;

This isn't a legal thing to do.  Struct addresses on ARM need to be
32-bit aligned, whereas &c is only guaranteed aligned to an 8-bit
boundary.  You can't, in general, take a pointer to an arbitrary type,
cast it to a struct and expect to get good results.

You need to use a union, or something like:

struct wrapped_char {
	char c;
}

struct wrapped_char wc;
wc.c = 0xf0;
bitfields &bf = &wc;

p.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: need help: cdrkit & bitifields
  2009-03-06  9:03     ` Phil Blundell
@ 2009-03-06  9:42       ` Frans Meulenbroeks
  2009-03-06 15:08         ` Phil Blundell
  0 siblings, 1 reply; 7+ messages in thread
From: Frans Meulenbroeks @ 2009-03-06  9:42 UTC (permalink / raw)
  To: openembedded-devel

2009/3/6 Phil Blundell <pb@reciva.com>:
> On Thu, 2009-03-05 at 22:10 +0100, Frans Meulenbroeks wrote:
>> main(int argc, char **argv)
>> {
>>     char c = 0xf0;
>>     bitfields *bf = &c;
>
> This isn't a legal thing to do.  Struct addresses on ARM need to be
> 32-bit aligned, whereas &c is only guaranteed aligned to an 8-bit
> boundary.  You can't, in general, take a pointer to an arbitrary type,
> cast it to a struct and expect to get good results.
>
> You need to use a union, or something like:
>
> struct wrapped_char {
>        char c;
> }
>
> struct wrapped_char wc;
> wc.c = 0xf0;
> bitfields &bf = &wc;
>
> p.
>

Hi Phil,

I understand the alignment issue.
However the problem occurs in code that I have not written and that is
not easy to modify.
I don't have the code handy but it could be that the code in cdrkit
works just the other way:
E.g. something like:
bitfields bf;
char *p = &bf;
*p = 0xf0;

I'll test that variant as well.
The stupid thing is that cdrkit words under opensuse/x68 but not under
oe/arm (LE).
So either this is a compiler issue or a nonportable construct.

Puzzled.
FM



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: need help: cdrkit & bitifields
  2009-03-06  9:42       ` Frans Meulenbroeks
@ 2009-03-06 15:08         ` Phil Blundell
  0 siblings, 0 replies; 7+ messages in thread
From: Phil Blundell @ 2009-03-06 15:08 UTC (permalink / raw)
  To: openembedded-devel

On Fri, 2009-03-06 at 10:42 +0100, Frans Meulenbroeks wrote:
> However the problem occurs in code that I have not written and that is
> not easy to modify.
> I don't have the code handy but it could be that the code in cdrkit
> works just the other way:

What I meant really was that the outcome of your test program might have
been influenced by alignment issues, and this might have been obscuring
the real situation with cdrtools.

> E.g. something like:
> bitfields bf;
> char *p = &bf;
> *p = 0xf0;

Right, this is safe.  Casting from a more restrictive type to "char*" is
always OK since there are no types with less restrictive alignment
requirements than char.

> I'll test that variant as well.
> The stupid thing is that cdrkit words under opensuse/x68 but not under
> oe/arm (LE).
> So either this is a compiler issue or a nonportable construct.

Yes, it seems.  My guess would be that it's a non-portable construct
somewhere rather than a compiler bug, but either is possible.

If it does turn out to be a struct alignment thing then you might be
able to work around it with judicious use of "__attribute__
((__packed__))".

It might also be worth checking out the ARM binary from Debian to see if
that behaves the same.

p.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: need help: cdrkit & bitifields
  2009-03-05 21:10   ` Frans Meulenbroeks
  2009-03-06  9:03     ` Phil Blundell
@ 2009-03-07  9:37     ` Khem Raj
  1 sibling, 0 replies; 7+ messages in thread
From: Khem Raj @ 2009-03-07  9:37 UTC (permalink / raw)
  To: openembedded-devel

On Thursday 05 March 2009 13:10:13 Frans Meulenbroeks wrote:
> 2009/3/5 Koen Kooi <k.kooi@student.utwente.nl>:
> > On 05-03-09 18:21, Frans Meulenbroeks wrote:
> >> Ucbit is an unsigned char
> >
> > unsigned char makes me think of
> > http://www.arm.linux.org.uk/docs/faqs/signedchar.php
> >
> > regards,
> >
> > Koen
>
> Well it is explictly defined as unsigned char.
> from utypes.h:
>
> /*
>  * The IBM AIX C-compiler seems to be the only compiler on the world
>  * which does not allow to use unsigned char bit fields as a hint
>  * for packed bit fields. Define a pesical type to avoid warnings.
>  * The packed attribute is honored wit unsigned int in this case too.
>  */
> #if     defined(_AIX) && !defined(__GNUC__)
>
> typedef unsigned int    Ucbit;
>
> #else
>
> typedef unsigned char   Ucbit;
>
> #endif
>
> The link you give is related to chars that are by default signed or
> unsigned
>
> This one seems to be related to whether bitfields are ordered left to
> right or right to left
> (and if I recall correctly in the ansi C standard this is undefined
> (but it has been a while since I checked)
>
> Decided to do some testing. On x86: gcc 4.3.2:
> frans@linux-suse:~/wt> cat tst.c
> #include <stdio.h>
>
> typedef struct {
>     unsigned char bit0:1;
>     unsigned char bits:6;
>     unsigned char bit7:1;
> } bitfields;
>
> main(int argc, char **argv)
> {
>     char c = 0xf0;
>     bitfields *bf = &c;
>
>     printf("bit 0 = %d, bits = %x, bit7 = %x\n", bf->bit0, bf->bits,
> bf->bit7); }
> frans@linux-suse:~/wt> gcc  tst.c
> tst.c: In function ‘main’:
> tst.c:12: warning: initialization from incompatible pointer type
> frans@linux-suse:~/wt> ./a.out
> bit 0 = 0, bits = 38, bit7 = 1
> frans@linux-suse:~/wt> gcc -O1 tst.c
> tst.c: In function ‘main’:
> tst.c:12: warning: initialization from incompatible pointer type
> frans@linux-suse:~/wt> ./a.out
> bit 0 = 0, bits = 38, bit7 = 1
> frans@linux-suse:~/wt> gcc -O2 tst.c
> tst.c: In function ‘main’:
> tst.c:12: warning: initialization from incompatible pointer type
> frans@linux-suse:~/wt> ./a.out
> bit 0 = 0, bits = 1c, bit7 = 1
> frans@linux-suse:~/wt> gcc -O3 tst.c
> tst.c: In function ‘main’:
> tst.c:12: warning: initialization from incompatible pointer type
> frans@linux-suse:~/wt> ./a.out
> bit 0 = 0, bits = 1c, bit7 = 1
>
> Same test on beagle (gcc 4.3.1), -O0  -O1 -O2 -O3
> root@beagleboard:~# ./tst0
> bit 0 = 0, bits = 38, bit7 = 1
> root@beagleboard:~# ./tst1
> bit 0 = 0, bits = 38, bit7 = 1
> root@beagleboard:~# ./tst2
> bit 0 = 0, bits = 20, bit7 = 0
> root@beagleboard:~# ./tst3
> bit 0 = 0, bits = 20, bit7 = 0
>
> Not sure what is happening here.
> I tried to compile cdrkit with -O1 using
> FULL_OPTIMIZATION = "-O1"
> FULL_OPTIMIZATION_armv7a = "-O1"
> BUILD_OPTIMIZATION = "${FULL_OPTIMIZATION}"
> but that did not help either.
>
> There is a compile time macro in gcc called BITS_BIG_ENDIAN but that
> one is set to 0 for arm (same as for x86).
>
> Puzzled....
Frans

There is a gcc bug here you are seeing when you use higher opt level. But this 
may not be cause of your problem here. You could try compiling with -Wcast-
align and see for any new warnings that will pop up. You then need to fix those 
cases.

You could also try -Wpadded and see if any structure is getting implicit 
padding.


Thx

-Khem



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-03-07  9:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-05 17:21 need help: cdrkit & bitifields Frans Meulenbroeks
2009-03-05 18:26 ` Koen Kooi
2009-03-05 21:10   ` Frans Meulenbroeks
2009-03-06  9:03     ` Phil Blundell
2009-03-06  9:42       ` Frans Meulenbroeks
2009-03-06 15:08         ` Phil Blundell
2009-03-07  9:37     ` Khem Raj

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.