Subject: known issues with bitfields on P-II/Celeron ?
To: None <port-i386@netbsd.org>
From: Darren Reed <darrenr@reed.wattle.id.au>
List: port-i386
Date: 10/01/2000 14:05:22
Maybe it is time I rebuilt my entire laptop (or reinstalled it) but in the
event that it's not, the following appears to cause a crash:

frentry_t *ipfrule_match_out(fin)
fr_info_t *fin;
{
        frentry_t *fr = NULL;
        u_32_t src = ntohl(fin->fin_fi.fi_saddr);
        u_32_t dst = ntohl(fin->fin_fi.fi_daddr);
 
        if (fin->fin_v == 4) {
        ^^^^^^^^^^^^^^^^^^^^^^

That particular line comes out (with -g, no -O) as:

.stabn 68,0,13703,.LM3153-ipfrule_match_out
.LM3153:
        movl 8(%ebp),%eax
        movzbl 4(%eax),%edx
        movl %edx,%eax
        andl $15,%eax
        cmpl $4,%eax
        jne .L2108

And the system panic's when processing the "movzbl".

That function is called with:

                        f = (*fn)(fin);
where fn and f are:

                        frentry_t * (* fn) __P((fr_info_t *)), *f;

(gdb) print fn
$1 = (frentry_t *(*)()) 0xc0199630 <ipfrule_match_out>
(gdb) print fin
$2 = (fr_info_t *) 0xdf35bd14
(gdb) print fin->fin_fi.fi_v
$3 = 33488900

With a crash dump, if I do "print *fin", I see:

(gdb) print *fin
$5 = {fin_ifp = 0xc0333be0, fin_fi = {fi_v = 33488900, fi_fl = 33488900, 
    fi_tos = 2130837248, fi_ttl = 8323583, fi_p = 32513, fi_src = {i6 = {
        16777343, 0, 0, 0}, in4 = {s_addr = 16777343}, ipoolnum = 16777343, 
      ipoolptr = 0x100007f}, fi_dst = {i6 = {16777343, 0, 0, 0}, in4 = {
        s_addr = 16777343}, ipoolnum = 16777343, ipoolptr = 0x100007f}, 
    fi_optmsk = 3227398144, fi_secmsk = 48512, fi_auth = 57141}, fin_data = {
    8, 0}, fin_out = 1 '\001', fin_rev = 0 '\000', fin_hlen = 20, 
  fin_tcpf = 0 '\000', fin_icode = 13 '\r', fin_rule = 0, fin_group = 0, 
  fin_fr = 0x0, fin_dp = 0xc05de2c0 "\b", fin_dlen = 64, fin_id = 12, 
  fin_mp = 0xdf35bde0, fin_plen = 84, fin_off = 0}

the following is the breakup of the first 5 fields of fin_fi:

        u_32_t  fi_v:4;         /* IP version */
        u_32_t  fi_fl:4;        /* packet flags */
        u_32_t  fi_tos:8;       /* IP packet TOS */
        u_32_t  fi_ttl:8;       /* IP packet TTL */
        u_32_t  fi_p:8;         /* IP packet protocol */

In ddb, it says:
Stopped in ping at ipfrule_match_out+0x3f: addl $0x4, 0(%eax)
show registers says "eax 0x4" which kind of makes it obvious why it
bailed.  t shows ipfrule_match_out was called with fin == 0xdf35bd14,
ebp is 0xdf35bc70, 8(ebp) == 0xdf35bd14 (so the stack doesn't appear
to be corrupt).  eip is actually ipfrule_match_out+0x3f which is
`inside' that movzbl (if that matters).  I can examine 0xdf35bd14
(0xc0333be0, 0x01ff0004, ...) without causing any page faults.  At
this point, edx also contains 0x4 (which is what I'd expect).

Can *anyone* shed any light as to what is going wrong here ?

Darren