* 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.