Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-02

does the following translation of a c struct to FPC is correct ?

6 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

ik

Hello,

I translated the following struct

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
	__u8	ihl:4,
		version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
	__u8	version:4,
  		ihl:4;
#else
#error	"Please fix <asm/byteorder.h>"
#endif
	__u8	tos;
	__be16	tot_len;
	__be16	id;
	__be16	frag_off;
	__u8	ttl;
	__u8	protocol;
	__sum16	check;
	__be32	saddr;
	__be32	daddr;
	/*The options start here. */
};

to the following Pascal record:

iphdr    = record
{$IFDEF ENDIAN_LITTLE}
              jhl     : Cardinal; // __u8	ihl:4,
              version : Cardinal; // version:4
{$ELSE}
              version : Cardinal; // __u8 version:4,
              jhl     : Cardinal; // version:4
{$ENDIF}
              tos      : cuint8;
              tot_len  : cint16;
              id       : cint16;
              frag_off : cint16;
              ttl      : cint8;
              protocol : cint8;
              check    : cuint16;
              saddr    : cint32;
              daddr    : cint32;
  end;

The problem is, that I get weird data in the fields, so I think I did not translate it properly, but can't figure out what have I missed.

Thanks,
Ido

Reply by email

ik
to ik

Answering myself:

ik wrote 32 lines
Hello, I translated the following struct struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD)        __u8    ihl:4,                version:4; #elif defined (__BIG_ENDIAN_BITFIELD)        __u8    version:4,                ihl:4; #else #error  "Please fix <asm/byteorder.h>" #endif        __u8    tos;        __be16  tot_len;        __be16  id;        __be16  frag_off;        __u8    ttl;        __u8    protocol;        __sum16 check;        __be32  saddr;        __be32  daddr;        /*The options start here. */ }; to the following Pascal record: iphdr    = record {$IFDEF ENDIAN_LITTLE}              jhl     : Cardinal; // __u8       ihl:4,
                           cuchar; // instead of Cardinal
Show quoted text 21 lines
             version : Cardinal; // version:4 {$ELSE}              version : Cardinal; // __u8 version:4,              jhl     : Cardinal; // version:4 {$ENDIF}              tos      : cuint8;              tot_len  : cint16;              id       : cint16;              frag_off : cint16;              ttl      : cint8;              protocol : cint8;              check    : cuint16;              saddr    : cint32;              daddr    : cint32;  end; The problem is, that I get weird data in the fields, so I think I did not translate it properly, but can't figure out what have I missed. Thanks, Ido

Reply by email

Jonas Maebe
to ik: I translated the following struct struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD)…
ik wrote 7 lines
to the following Pascal record: iphdr = record {$IFDEF ENDIAN_LITTLE} jhl : Cardinal; // __u8 ihl:4, version : Cardinal; // version:4

The ":4" in C means "4 bits", not 4 bytes. The correct translation in the general case for bitfields is hard, because FPC does not support C-compatible bitpacking (it depends on the type of the bitfield, e.g. "int a:4;" and "char a:4" have different alignment rules). In this case, this should match the C layout:

{$packrecords c}
iphdr    = record
             bitfields = bitpacked record
{$IFDEF ENDIAN_LITTLE}
               jhl: 0..(1 shl 4)-1;
               version: 0..(1 shl 4)-1;
{$ELSE}
               jhl: 0..(1 shl 4)-1;
               version: 0..(1 shl 4)-1;
{$ENDIF}
             end;
             tos      : cuint8;
             tot_len  : cint16;
             id       : cint16;
             frag_off : cint16;
             ttl      : cint8;
             protocol : cint8;
             check    : cuint16;
             saddr    : cint32;
             daddr    : cint32;
 end;

You will then of course have to use iphdrvar.bitfields.jhl instead of iphdrvar.jhl.

Jonas

Reply by email

ik
to Jonas Maebe
Jonas Maebe wrote 36 lines
On 26 Feb 2012, at 13:54, ik wrote: > to the following Pascal record: > > > iphdr    = record > {$IFDEF ENDIAN_LITTLE} >              jhl     : Cardinal; // __u8      ihl:4, >              version : Cardinal; // version:4 The ":4" in C means "4 bits", not 4 bytes. The correct translation in the general case for bitfields is hard, because FPC does not support C-compatible bitpacking (it depends on the type of the bitfield, e.g. "int a:4;" and "char a:4" have different alignment rules). In this case, this should match the C layout: {$packrecords c} iphdr    = record             bitfields = bitpacked record {$IFDEF ENDIAN_LITTLE}               jhl: 0..(1 shl 4)-1;               version: 0..(1 shl 4)-1; {$ELSE}               jhl: 0..(1 shl 4)-1;               version: 0..(1 shl 4)-1; {$ENDIF}             end;             tos      : cuint8;             tot_len  : cint16;             id       : cint16;             frag_off : cint16;             ttl      : cint8;             protocol : cint8;             check    : cuint16;             saddr    : cint32;             daddr    : cint32;  end; You will then of course have to use iphdrvar.bitfields.jhl instead of iphdrvar.jhl.

I'ved replaced it to

iphdr    = bitpacked record
{$IFDEF ENDIAN_LITTLE}
              jhl     : 0..(1 shl 4)-1; // __u8	ihl:4,
              version : 0..(1 shl 4)-1; // version:4
{$ELSE}
              version : 0..(1 shl 4)-1; // __u8 version:4,
              jhl     : 0..(1 shl 4)-1; // version:4
{$ENDIF}
              tos      : cuint8;
              tot_len  : cint16;
              id       : cint16;
              frag_off : cint16;
              ttl      : cint8;
              protocol : cint8;
              check    : cuint16;
              saddr    : cint32;
              daddr    : cint32;
  end;

And now all of the problems that I continue to find gone away.

Thank you

Show quoted text 5 lines
Jonas_______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Jonas Maebe
to ik
ik wrote
I'ved replaced it to iphdr = bitpacked record

This is wrong. The record is a C record, and hence follows {$packrecord c} rules. "bitpacked record" overrides any current {$packrecords x} setting. That is the reason why I used the nested bitpacked record.

And now all of the problems that I continue to find gone away.

You may get lucky, but it's still wrong.

Jonas

Reply by email

ik
to Jonas Maebe
Jonas Maebe wrote 12 lines
On 26 Feb 2012, at 14:16, ik wrote: > I'ved replaced it to > > iphdr    = bitpacked record This is wrong. The record is a C record, and hence follows {$packrecord c} rules. "bitpacked record" overrides any current {$packrecords x} setting. That is the reason why I used the nested bitpacked record. > And now all of the problems that I continue to find gone away. You may get lucky, but it's still wrong.

I understand, so I'll change it, to your way

Show quoted text 5 lines
Jonas_______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email