Hello,
After noticing that gdb does not print 64 bit fields of (bit)packed records properly if they don't start on a byte boundary (both with fpc and with gpc), I decided to check what gcc does. It turns out that gcc (4.0.1, Mac OS X/ppc) only bitpacks values up to and including 59 bits. Fields declared as 60-64 bits are automatically aligned to the target-specific alignment boundary.
Does anyone here know why this is the case, and possibly where this is documented? I can't find anything with Google.
Thanks,
Jonas
Simple test case follows (compile with -c -gdwarf-2, then use dwarfdump/elfread --debug-dump on the .o file to look at the debug info). both l and l2 are aligned on an 8 byte boundary for ppc64 and to a 4 byte boundary for ppc32.
*** struct tt { int a; int j; };
struct S { int j:5; long long l:60; long long l2:60; int k:6; int m:5; int n:8; struct tt s; };
int main(struct S s) { } ***
Compare with a Pascal program:
*** {$ifdef fpc} {$bitpacking on} {$endif}
type {$ifndef fpc} int64 = longint; {$endif} tenum = (ea,eb,ec,ed,ee,ef,eg,eh); tr = packed record a: 0..3; // 2 bits i: int64; c: boolean; // 1 bit d: 0..31; // 5 bits e: tenum; // 3 bits end;
procedure t(var r2: tr); var r: tr; begin r.a := 2; r.i := 1234567890123456789; r.c := true; r.d := 5; r.e := ed; r2 := r; end;
var r: tr;
begin t(r); if (r.a <> 2) or (r.i <> 1234567890123456789) or (not r.c) or (r.d <> 5) or (r.e <> ed) then halt(1); end. ***
If you debug this, step over the "t" call and print r, you get (for gpc):
(gdb) p r $1 = { A = 2, I = 0, C = true, D = 5, E = Ed } (gdb) ptype r type = record A : 0..3 : 2; I : Int64 : 64; C : Boolean : 1; D : 0..31 : 5; E : Tenum : 3; end
Looking at the stabs (the gpc for Mac OS X I have doesn't support dwarf), gpc also puts the 64 bit int right after the two first bits, without aligning to a byte/4 byte/8 byte boundary first.
On 12 jun 2007, at 13:45, Jonas Maebe wrote:
After noticing that gdb does not print 64 bit fields of (bit)packed records properly if they don't start on a byte boundary (both with fpc and with gpc), I decided to check what gcc does. It turns out that gcc (4.0.1, Mac OS X/ppc) only bitpacks values up to and including 59 bits. Fields declared as 60-64 bits are automatically aligned to the target-specific alignment boundary.
I've found my answer: http://www.linux-foundation.org/spec/ELF/ppc64/PPC- elf64abi-1.9.html#BITFIELD
Bit fields cause records to be split up in "storage units", and a field cannot cross the boundary of such a storage unit. If it does, then you have to pad the rest of the previous storage unit and start a new one for the current field (something which fpc does not yet do, and gpc apparently also not in all cases, at least not in "gpc version 20051116, based on gcc-3.4.5" for Mac OS X, which is of course fairly old).
And to make things more fun, there are apparently a lot of differences regarding how large such a "storage unit" is...
Jonas
Jonas Maebe wrote:
On 12 jun 2007, at 13:45, Jonas Maebe wrote:
After noticing that gdb does not print 64 bit fields of (bit)packed records properly if they don't start on a byte boundary (both with fpc and with gpc), I decided to check what gcc does. It turns out that gcc (4.0.1, Mac OS X/ppc) only bitpacks values up to and including 59 bits. Fields declared as 60-64 bits are automatically aligned to the target-specific alignment boundary.
I've found my answer: http://www.linux-foundation.org/spec/ELF/ppc64/PPC- elf64abi-1.9.html#BITFIELD
Bit fields cause records to be split up in "storage units", and a field cannot cross the boundary of such a storage unit. If it does, then you have to pad the rest of the previous storage unit and start a new one for the current field (something which fpc does not yet do, and gpc apparently also not in all cases, at least not in "gpc version 20051116, based on gcc-3.4.5" for Mac OS X, which is of course fairly old).
And to make things more fun, there are apparently a lot of differences regarding how large such a "storage unit" is...
AFAIK this padding is part of C language specification. What other langages do is subject to language/compiler specification. In particular, I think that Ada requires support for arbitrary bitfield layout (including bitfields that go across word boundaries). I belive that current gpc behaviour is a concious decision to have better semantics that the one given by C. gcc backends is flexible, AFAIK gpc just uses backend support.
IMHO gdb should just correctly display such bitfields in gpc generated programs -- if not there is bug somewhere. ATM I can not say if the bug is in gpc frontend (missing some annotations) gcc buckend (emmiting incorrect debug info), gdb (mishandling debug info) or maybe brain damaged specification of debug info (basic stabs can handle only simple cases and frequently require nonstandard extensions).
On 13 jun 2007, at 04:09, Waldek Hebisch wrote:
AFAIK this padding is part of C language specification.
Yesterday, during my searches I found a gcc internals document which said that the C language specification defines it as part of the ABI specification. I can't find it anymore now though.
What other langages do is subject to language/compiler specification. In particular, I think that Ada requires support for arbitrary bitfield layout (including bitfields that go across word boundaries). I belive that current gpc behaviour is a concious decision to have better semantics that the one given by C. gcc backends is flexible, AFAIK gpc just uses backend support.
gcc indeed supports several different ways to bitpack (based on directives, e.g. there's one for MSVC-compatible bitpacking).
IMHO gdb should just correctly display such bitfields in gpc generated programs -- if not there is bug somewhere. ATM I can not say if the bug is in gpc frontend (missing some annotations) gcc buckend (emmiting incorrect debug info), gdb (mishandling debug info) or maybe brain damaged specification of debug info (basic stabs can handle only simple cases and frequently require nonstandard extensions).
The debug info looks standard and fine to me. I think it's a bug in the gdb value reading routine.
Jonas