I have found a problem handling bit-wide fields in TinyCC. Attached is a test 
log. I'm
no compiler expert and I have no time to solve it myself. Would be nice to have 
this
bug removed for fast scripting in networking applications :-)

Thanks, /PA
                                          
#include <stdio.h>
#include <errno.h>
// ntoh... & hton...
#include <arpa/inet.h>
#include <netinet/ip.h>

//
// the original header uses
//   unsigned int ihl:4;
//   unsigned int version:4;
//
struct my_iphdr
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t ihl:4;
    u_int8_t version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t version:4;
    u_int8_t ihl:4;
#else
# error	"Please fix <bits/endian.h>"
#endif
    u_int8_t tos;
    u_int16_t tot_len;
    u_int16_t id;
    u_int16_t frag_off;
    u_int8_t ttl;
    u_int8_t protocol;
    u_int16_t check;
    u_int32_t saddr;
    u_int32_t daddr;
    /*The options start here. */
  }__attribute__((__packed__));
  
void printbuf(u_int8_t *p,int len) {
    for (int i=0;i<len;i++) {
	printf("%02x ",p[i]);
	if ((i & 7) == 7)
	    printf("\n");
    }
    printf("\n");
}

int main(int argc,char **argv) {
    struct my_iphdr test;
    struct iphdr test2;
    
    printf("while my_iphdr is %d bytes long\n",
	    sizeof(struct my_iphdr));
    
    u_int8_t *p1 = (u_int8_t *)&test;
    test.version  = 4;
    test.ihl      = 5;
    test.tos      = 1;
    test.tot_len  = htons(2);
    test.id       = htons(3);
    test.frag_off = htons(4);
    test.ttl      = 5;
    test.protocol = 6;
    test.check    = htons(7);
    test.saddr    = htonl(8);
    test.daddr    = htonl(9);
    printf("my_iphdr: the first byte: 0x%02x\n",*(u_int8_t *)&test);
    u_int8_t *p2 = (u_int8_t *)&test.tos;
    printf("          tos      is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.tot_len;
    printf("          tot_len  is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.id;
    printf("          id       is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.frag_off;
    printf("          frag_off is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.ttl;
    printf("          ttl      is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.protocol;
    printf("          protocol is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.check;
    printf("          check    is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.saddr;
    printf("          saddr    is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test.daddr;
    printf("          daddr    is as offset %d\n",p2-p1);
    printf("\n");
    printbuf((u_int8_t *)&test,sizeof(test));
    printf("\n");
    
    printf("the iphdr is %d bytes long\n",
	    sizeof(struct iphdr));
    test2.version  = 4;
    test2.ihl      = 5;
    test2.tos      = 1;
    test2.tot_len  = htons(2);
    test2.id       = htons(3);
    test2.frag_off = htons(4);
    test2.ttl      = 5;
    test2.protocol = 6;
    test2.check    = htons(7);
    test2.saddr    = htonl(8);
    test2.daddr    = htonl(9);
    p1 = (u_int8_t *)&test2;
    printf("iphdr:    the first byte: 0x%02x\n",*(u_int8_t *)&test2);
    p2 = (u_int8_t *)&test2.tos;
    printf("          tos      is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.tot_len;
    printf("          tot_len  is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.id;
    printf("          id       is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.frag_off;
    printf("          frag_off is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.ttl;
    printf("          ttl      is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.protocol;
    printf("          protocol is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.check;
    printf("          check    is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.saddr;
    printf("          saddr    is as offset %d\n",p2-p1);
    p2 = (u_int8_t *)&test2.daddr;
    printf("          daddr    is as offset %d\n",p2-p1);
    printf("\n");
    printbuf((u_int8_t *)&test2,sizeof(test2));
    printf("\n");
}
paag@paag-laptop:~/devel$ gcc --version
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
paag@paag-laptop:~/devel$ gcc -std=gnu99 -o kk kk.c
paag@paag-laptop:~/devel$ ./kk
while my_iphdr is 20 bytes long
my_iphdr: the first byte: 0x45
          tos      is as offset 1
          tot_len  is as offset 2
          id       is as offset 4
          frag_off is as offset 6
          ttl      is as offset 8
          protocol is as offset 9
          check    is as offset 10
          saddr    is as offset 12
          daddr    is as offset 16

45 01 00 02 00 03 00 04 
05 06 00 07 00 00 00 08 
00 00 00 09 

the iphdr is 20 bytes long
iphdr:    the first byte: 0x45
          tos      is as offset 1
          tot_len  is as offset 2
          id       is as offset 4
          frag_off is as offset 6
          ttl      is as offset 8
          protocol is as offset 9
          check    is as offset 10
          saddr    is as offset 12
          daddr    is as offset 16

45 01 00 02 00 03 00 04 
05 06 00 07 00 00 00 08 
00 00 00 09 

paag@paag-laptop:~/devel$ tcc -run kk.c
while my_iphdr is 20 bytes long
my_iphdr: the first byte: 0x45
          tos      is as offset 1
          tot_len  is as offset 2
          id       is as offset 4
          frag_off is as offset 6
          ttl      is as offset 8
          protocol is as offset 9
          check    is as offset 10
          saddr    is as offset 12
          daddr    is as offset 16

45 01 00 02 00 03 00 04 
05 06 00 07 00 00 00 08 
00 00 00 09 

the iphdr is 24 bytes long
iphdr:    the first byte: 0x45
          tos      is as offset 4
          tot_len  is as offset 6
          id       is as offset 8
          frag_off is as offset 10
          ttl      is as offset 12
          protocol is as offset 13
          check    is as offset 14
          saddr    is as offset 16
          daddr    is as offset 20

45 76 9a 08 01 21 00 02 
00 03 00 04 05 06 00 07 
00 00 00 08 00 00 00 09 

paag@paag-laptop:~/devel$ apt-show-versions | grep tinycc
tinycc 110318git-1 installed: No available version in archive
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to