This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

egcs/linux networking problem isolated


I bootstrapped egcs-2.93.17 the other evening and tried compiling
linux-2.2.5 for i586.  It was rather disconcerting to find networking
completely broken; even "ping localhost" failed...  Scanned the egcs-bugs
archive to find this is a known problem with recent snapshots, but not
resolved yet.

Anyway, to cut a long story short, after much recompiling with gcc-2.7.2
and egcs, I narrowed the problem down to a memcpy in
linux/net/ipv4/ip_output.c

Here's an extract from the source:

int ip_output(struct sk_buff *skb)
{
#ifdef CONFIG_IP_ROUTE_NAT
        struct rtable *rt = (struct rtable*)skb->dst;
#endif

        ip_statistics.IpOutRequests++;

#ifdef CONFIG_IP_ROUTE_NAT
        if (rt->rt_flags&RTCF_NAT)
                ip_do_nat(skb);
#endif

        return ip_finish_output(skb);
}

with ip_finish_output defined in linux/include/net/ip.h

extern __inline__ int ip_finish_output(struct sk_buff *skb)
{
        struct dst_entry *dst = skb->dst;
        struct device *dev = dst->dev;
        struct hh_cache *hh = dst->hh;

        skb->dev = dev;
        skb->protocol = __constant_htons(ETH_P_IP);

        if (hh) {
                read_lock_irq(&hh->hh_lock);
                memcpy(skb->data - 16, hh->hh_data, 16);
                read_unlock_irq(&hh->hh_lock);
                skb_push(skb, dev->hard_header_len);
                return hh->hh_output(skb);
        } else if (dst->neighbour)
                return dst->neighbour->output(skb);

        kfree_skb(skb);
        return -EINVAL;
}

egcs generated code from the above memcpy

     3a2:       85 f6                   test   %esi,%esi
     3a4:       74 5a                   je     400 <ip_output+0x80>
     3a6:       fa                      cli            # read_lock_irq
     3a7:       8b 8b 80 00 00 00       mov    0x80(%ebx),%ecx
     3ad:       8d 56 10                lea    0x10(%esi),%edx
     3b0:       8b 46 10                mov    0x10(%esi),%eax
     3b3:       89 41 f0                mov    %eax,0xfffffff0(%ecx)
     3b6:       8b 42 04                mov    0x4(%edx),%eax
     3b9:       89 41 f4                mov    %eax,0xfffffff4(%ecx)
     3bc:       8b 42 08                mov    0x8(%edx),%eax
     3bf:       89 41 f8                mov    %eax,0xfffffff8(%ecx)
     3c2:       8b 42 0c                mov    0xc(%edx),%eax
     3c5:       89 41 fc                mov    %eax,0xfffffffc(%ecx)
     3c8:       fb                      sti            # read_unlock_irq

gcc-2.7.2 generated code

     367:       85 f6                   test   %esi,%esi
     369:       74 53                   je     3be <ip_output+0x75>
     36b:       fa                      cli
     36c:       8b 93 80 00 00 00       mov    0x80(%ebx),%edx
     372:       8b 46 14                mov    0x14(%esi),%eax
     375:       89 42 f0                mov    %eax,0xfffffff0(%edx)
     378:       8b 46 18                mov    0x18(%esi),%eax
     37b:       89 42 f4                mov    %eax,0xfffffff4(%edx)
     37e:       8b 46 1c                mov    0x1c(%esi),%eax
     381:       89 42 f8                mov    %eax,0xfffffff8(%edx)
     384:       8b 46 20                mov    0x20(%esi),%eax
     387:       89 42 fc                mov    %eax,0xfffffffc(%edx)
     38a:       fb                      sti

Notice how the read locations are off!  egcs reads from 0x10(%esi) to
0x1c(%esi), while gcc-2.7.2 reads from 0x14(%esi) to 0x20(%esi).

cc'd to linux-kernel for general interest - this one doesn't look like
a linux bug.  Hope there's enough info here for egcs gurus to squash this
one.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]