Gert Doering <g...@greenie.muc.de> writes:

> Hi,
>
> On Sat, Jun 10, 2017 at 07:58:13PM +0200, Jeremie Courreges-Anglas wrote:
>> OpenBSD:
>> 
>> struct ip {
>> #if _BYTE_ORDER == _LITTLE_ENDIAN
>>      u_int     ip_hl:4,              /* header length */
>>                ip_v:4;               /* version */
>> #endif
>> #if _BYTE_ORDER == _BIG_ENDIAN
>>      u_int     ip_v:4,               /* version */
>>                ip_hl:4;              /* header length */
>> #endif
>> ...
>> 
>> u_char -> u_int.  Dunno if it matters to the compiler, I can take a look
>> later.
>
> I'm fairly sure it does matter.  An int is likely to be at least 16 bit, 
> maybe 32 bit, so the compiler can assume "word aligned" - and *boom*.

It doesn't seem to matter that much.  Which aligns well with the
"bit fields are nasty" experience people seem to have.  From a quick
glance at the c99 standard, I couldn't find language about this.

  "A bit-field shall have a type that is a qualified or unqualified version
  of _Bool, signed int, unsigned int, or some other implementation-defined
  type."


Here's a snippet:

--8<--
#include <sys/types.h>

#include <netinet/in.h>

#include <endian.h>
#include <stdlib.h>

struct ip {
#if _BYTE_ORDER == _LITTLE_ENDIAN
        u_int     ip_hl:4,              /* header length */
                  ip_v:4;               /* version */
#endif
#if _BYTE_ORDER == _BIG_ENDIAN
        u_int     ip_v:4,               /* version */
                  ip_hl:4;              /* header length */
#endif
        u_int8_t  ip_tos;               /* type of service */
        u_int16_t ip_len;               /* total length */
        u_int16_t ip_id;                /* identification */
        u_int16_t ip_off;               /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */

#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
        u_int8_t  ip_ttl;               /* time to live */
        u_int8_t  ip_p;                 /* protocol */
        u_int16_t ip_sum;               /* checksum */
        struct    in_addr ip_src, ip_dst; /* source and dest address */
};

struct ip_freebsd {
#if _BYTE_ORDER == _LITTLE_ENDIAN
        u_char     ip_hl:4,             /* header length */
                  ip_v:4;               /* version */
#endif
#if _BYTE_ORDER == _BIG_ENDIAN
        u_char     ip_v:4,              /* version */
                  ip_hl:4;              /* header length */
#endif
        u_int8_t  ip_tos;               /* type of service */
        u_int16_t ip_len;               /* total length */
        u_int16_t ip_id;                /* identification */
        u_int16_t ip_off;               /* fragment offset field */
#define IP_RF 0x8000                    /* reserved fragment flag */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
        u_int8_t  ip_ttl;               /* time to live */
        u_int8_t  ip_p;                 /* protocol */
        u_int16_t ip_sum;               /* checksum */
        struct    in_addr ip_src, ip_dst; /* source and dest address */
};


void
f(void *p)
{
        struct ip *iph;

        iph = (struct ip *)p;

        if (iph->ip_v == 6)
                abort();
}

void
g(void *p)
{
        struct ip_freebsd *iph;

        iph = (struct ip_freebsd *)p;

        if (iph->ip_v == 6)
                abort();
}

--8<--

gcc-4.2.1 (system compiler on OpenBSD)

(gdb) disas f
Dump of assembler code for function f:
0x0000000000000040 <f+0>:       save  %sp, -208, %sp
0x0000000000000044 <f+4>:       ld  [ %i0 ], %g1
0x0000000000000048 <f+8>:       sethi  %hi(0xf0000000), %g2
0x000000000000004c <f+12>:      sethi  %hi(0x60000000), %g3
0x0000000000000050 <f+16>:      and  %g1, %g2, %g1
0x0000000000000054 <f+20>:      cmp  %g1, %g3
0x0000000000000058 <f+24>:      be,pn   %icc, 0x68 <f+40>
0x000000000000005c <f+28>:      nop
0x0000000000000060 <f+32>:      rett  %i7 + 8
0x0000000000000064 <f+36>:      nop
0x0000000000000068 <f+40>:      call  0x68 <f+40>
0x000000000000006c <f+44>:      nop
0x0000000000000070 <f+48>:      nop
End of assembler dump.
(gdb) disas g
Dump of assembler code for function g:
0x0000000000000000 <g+0>:       save  %sp, -208, %sp
0x0000000000000004 <g+4>:       ld  [ %i0 ], %g1
0x0000000000000008 <g+8>:       sethi  %hi(0xf0000000), %g2
0x000000000000000c <g+12>:      sethi  %hi(0x60000000), %g3
0x0000000000000010 <g+16>:      and  %g1, %g2, %g1
0x0000000000000014 <g+20>:      cmp  %g1, %g3
0x0000000000000018 <g+24>:      be,pn   %icc, 0x28 <g+40>
0x000000000000001c <g+28>:      nop
0x0000000000000020 <g+32>:      rett  %i7 + 8
0x0000000000000024 <g+36>:      nop
0x0000000000000028 <g+40>:      call  0x28 <g+40>
0x000000000000002c <g+44>:      nop
0x0000000000000030 <g+48>:      nop
End of assembler dump.

gcc 4.9.4:

(gdb) disas f
Dump of assembler code for function f:
0x0000000000000000 <f+0>:       save  %sp, -176, %sp
0x0000000000000004 <f+4>:       ld  [ %i0 ], %g2
0x0000000000000008 <f+8>:       sethi  %hi(0xf0000000), %g1
0x000000000000000c <f+12>:      and  %g2, %g1, %g1
0x0000000000000010 <f+16>:      sethi  %hi(0x60000000), %g2
0x0000000000000014 <f+20>:      cmp  %g1, %g2
0x0000000000000018 <f+24>:      be,pn   %icc, 0x28 <f+40>
0x000000000000001c <f+28>:      nop
0x0000000000000020 <f+32>:      rett  %i7 + 8
0x0000000000000024 <f+36>:      nop
0x0000000000000028 <f+40>:      call  0x28 <f+40>
0x000000000000002c <f+44>:      nop
0x0000000000000030 <f+48>:      nop
End of assembler dump.
(gdb) disas g
Dump of assembler code for function g:
0x0000000000000040 <g+0>:       save  %sp, -176, %sp
0x0000000000000044 <g+4>:       ld  [ %i0 ], %g2
0x0000000000000048 <g+8>:       sethi  %hi(0xf0000000), %g1
0x000000000000004c <g+12>:      and  %g2, %g1, %g1
0x0000000000000050 <g+16>:      sethi  %hi(0x60000000), %g2
0x0000000000000054 <g+20>:      cmp  %g1, %g2
0x0000000000000058 <g+24>:      be,pn   %icc, 0x68 <g+40>
0x000000000000005c <g+28>:      nop
0x0000000000000060 <g+32>:      rett  %i7 + 8
0x0000000000000064 <g+36>:      nop
0x0000000000000068 <g+40>:      call  0x68 <g+40>
0x000000000000006c <g+44>:      nop
0x0000000000000070 <g+48>:      nop
End of assembler dump.

So, no difference in the generated code between the OpenBSD and FreeBSD
structures.

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Attachment: signature.asc
Description: PGP signature

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to