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