tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Bug in NetBSD compiler or "bus.h" header file crashes my ISDN4BSD
Hi,
Summed up:
==========
It appears that because the bus_space_xxx functions are implemented like
macros this can cause errors in the generated code! The following code is
excuted when filtering on the "%cx" register:
hfc4s8s_fifo_write:
0xcd71796a: movw 0xffffffda(%ebp),%cx //0x8
0xcd71796e: shrw $0x2,%cx //0x2
...
bus_space_write_multi_4:
0xcd7179df: lodsl (%esi) // valid address
0xcd7179e0: movl %eax,0(%edx) //valid address
0xcd7179e2: loop 0xcd7179df // uses %ecx, but only %cx was initialised
I use a 16-bit length variable which I pass to "bus_space_write_multi_4" as
the last argument. This is actually the "count". I suspect that somehow the
upper 16-bits of the %ecx register never gets initialised --- oops. Is this a
bug in the NetBSD compiler or in the "bus.h" header file ?
Full details:
=============
First of all. I would like to wish that the NetBSD kernel would load the
symbols from kernel modules and resolve these when the kernel panics, hence
my software is a kernel module. Anyway here goes:
db> bt
_prop_dictionary_keysym32_pool(c312a000,c312ad94,c2a90938,8,c312a000) at
0xcd717
9df
_prop_dictionary_keysym32_pool(c312ad94,c312a000,cd3f2abc,cd716987,c312a000)
at 0
xcd713fed
_prop_dictionary_keysym32_pool(c312a000,c312ad94,cd3f2abc,cd7168e9,c312ad94)
at 0
xcd7148a0
_prop_dictionary_keysym32_pool(c312a000,c312ad94,cd73f828,341,c312a93c) at
0xcd7
16987
_prop_dictionary_keysym32_pool(c312a000,8,3,7,0) at 0xcd715516
_prop_dictionary_keysym32_pool(c312a000,22bf98,cd3f2b5c,c04390ca,c09c3ac0) at
0x
cd715c2d
_prop_dictionary_keysym32_pool(c3116000,0,dd310010,30,c0970010) at 0xcd700075
Xintr_ioapic_level20() at netbsd:Xintr_ioapic_level20+0x9b
--- interrupt ---
Xspllower(0,c09993c4,7,6,c04338c1) at netbsd:Xspllower+0xe
mpidle(cc8ac2e4,0,0,cc8ac2e4,103) at netbsd:mpidle+0xd7
preempt(0,4,cc8bde88,8062000,3ff0) at netbsd:preempt+0x5d
trap() at netbsd:trap+0x6bb
--- trap (number 3) ---
The topmost function translates to the following function:
_prop_dictionary_keysym32_pool(c312a000,c312ad94,c2a90938,8,c312a000)
>>>>
static void
hfc4s8s_fifo_write FIFO_WRITE_T(sc,f,ptr,len)
{
HFC4S8S_BUS_VAR(sc);
u_int16_t temp;
if(len)
{
f->last_byte = ptr[len-1];
/* pre increment Z-counter, before "len" is changed */
f->Z_drvr += len;
if(f->Z_drvr >= f->fm.h.Zend)
{
f->Z_drvr -= f->fm.h.Zsize;
}
temp = len & 3;
if(temp)
{
bus_space_write_multi_1(t,h,REG_hfc4s8s_a_fifo_data,ptr,temp);
ptr += temp;
}
len /= 4;
if(len)
{
// HERE IT PANICS:
bus_space_write_multi_4(t,h,REG_hfc4s8s_a_fifo_data,(const
u_int32_t *)ptr,len);
}
}
return;
}
hfc4s8s_fifo_write:
0xcd717915: leal 0(%esi),%esi
0xcd717918: pushl %ebp
0xcd717919: movl %esp,%ebp
0xcd71791b: pushl %edi
0xcd71791c: pushl %esi
0xcd71791d: pushl %ebx
0xcd71791e: subl $0x1c,%esp
0xcd717921: movl 0x8(%ebp),%eax //0xc312a000
0xcd717924: movl 0xc(%ebp),%ecx //0xc312ad94
0xcd717927: movl 0x10(%ebp),%edi //0xc2a90938
0xcd71792a: movl 0x14(%ebp),%edx //0x8
0xcd71792d: movw %dx,0xffffffda(%ebp) //0x8
0xcd717931: movl 0x3a4(%eax),%esi //0x1
0xcd717937: movl %esi,0xffffffdc(%ebp) //0x1
0xcd71793a: movl 0x3b0(%eax),%eax //0xcd427000
0xcd717940: movl %eax,0xffffffe0(%ebp) //0xcd427000
0xcd717943: testw %dx,%dx
0xcd717946: jz 0xcd71798c //not jumped
0xcd717948: movzwl %edx,%eax //0x8
0xcd71794b: movb 0xffffffff(%eax,%edi,1),%al //0xff
0xcd71794f: movb %al,0x14(%ecx)
0xcd717952: movl %edx,%eax //0x8
0xcd717954: addl 0x74(%ecx),%eax
0xcd717957: movw %ax,0x74(%ecx)
0xcd71795b: cmpw 0xc(%ecx),%ax
0xcd71795f: jnb 0xcd7179c0 //not jumped
0xcd717961: movw 0xffffffda(%ebp),%bx //0x8
0xcd717965: andl $0x3,%ebx //0x0
0xcd717968: jnz 0xcd717994 //not jumped
0xcd71796a: movw 0xffffffda(%ebp),%cx //0x8
0xcd71796e: shrw $0x2,%cx //0x2
0xcd717972: jz 0xcd71798c //not jumped
0xcd717974: movl 0xffffffdc(%ebp),%eax //0x1
0xcd717977: testl %eax,%eax
0xcd717979: jnz 0xcd7179d4 // jumped
0xcd71797b: movl 0xffffffe0(%ebp),%edx
0xcd71797e: subl $-0x80,%edx
0xcd717981: movzwl %ecx,%ecx
0xcd717984: movl %edi,%esi
0xcd717986: cld
0xcd717987: repe outsl (%esi),%dx
0xcd717989: leal 0(%esi),%esi
0xcd71798c: addl $0x1c,%esp
0xcd71798f: popl %ebx
0xcd717990: popl %esi
0xcd717991: popl %edi
0xcd717992: leave
0xcd717993: ret
0xcd717994: movl 0xffffffdc(%ebp),%eax
0xcd717997: testl %eax,%eax
0xcd717999: jz 0xcd7179ec
0xcd71799b: movl 0xffffffe0(%ebp),%eax
0xcd717992: leave
0xcd717993: ret
0xcd717994: movl 0xffffffdc(%ebp),%eax
0xcd717997: testl %eax,%eax
0xcd717999: jz 0xcd7179ec
0xcd71799b: movl 0xffffffe0(%ebp),%eax
0xcd71799e: subl $-0x80,%eax
0xcd7179a1: movl %edi,%esi
0xcd7179a3: movl %ebx,%ecx
0xcd7179a5: movl %eax,%edx
0xcd7179a7: cld
0xcd7179a8: lodsb (%esi)
0xcd7179a9: movb %al,0(%edx)
0xcd7179ab: loop 0xcd7179a8
0xcd7179ad: movzwl %ebx,%eax
0xcd7179b0: addl %eax,%edi
0xcd7179b2: movw 0xffffffda(%ebp),%cx
0xcd7179b6: shrw $0x2,%cx
0xcd7179ba: jnz 0xcd717974
0xcd7179bc: jmp 0xcd71798c
0xcd7179be: movl %esi,%esi
0xcd7179c0: subw 0x2(%ecx),%ax
0xcd7179c4: movw %ax,0x74(%ecx)
0xcd7179c8: movw 0xffffffda(%ebp),%bx
0xcd7179cc: andl $0x3,%ebx
0xcd7179cf: jz 0xcd71796a
0xcd7179d1: jmp 0xcd717994
0xcd7179d3: nop
// continues here
0xcd7179d4: movl 0xffffffe0(%ebp),%eax //0xcd427000
0xcd7179d7: subl $-0x80,%eax //0xcd427080
0xcd7179da: movl %edi,%esi //0xc2a90938
0xcd7179dc: movl %eax,%edx //0xcd427080
0xcd7179de: cld
0xcd7179df: lodsl (%esi)
0xcd7179e0: movl %eax,0(%edx)
//
// OOOPS OOOPS OOOPS
//
// The "loop" will decrement "%ecx" and not "%cx" ???
//
0xcd7179e2: loop 0xcd7179df
0xcd7179e4: addl $0x1c,%esp
0xcd7179e7: popl %ebx
0xcd7179e8: popl %esi
0xcd7179e9: popl %edi
0xcd7179ea: leave
0xcd7179eb: ret
http://fxr.watson.org/fxr/source/arch/x86/include/bus.h?v=NETBSD4#L550
550 #define bus_space_write_multi_4(t, h, o, ptr, cnt) \
551 do { \
552 __BUS_SPACE_ADDRESS_SANITY((ptr), u_int32_t, "buffer"); \
553 __BUS_SPACE_ADDRESS_SANITY((h) + (o), u_int32_t, "bus addr"); \
554 if ((t) == X86_BUS_SPACE_IO) { \
555 outsl((h) + (o), (ptr), (cnt)); \
556 } else { \
557 void *dummy1; \
558 int dummy2; \
559 void *dummy3; \
560 int __x; \
561 __asm volatile(" \
562 cld ; \
563 1: lodsl ; \
564 movl %%eax,(%2) ; \
565 loop 1b" : \
566 "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a"
(__x) : \
567 "" ((ptr)), "1" ((cnt)), "2" ((h) + (o))); \
568 } \
569 } while (/* CONSTCOND */ 0)
db> show registers
ds 0x10
es 0x10
fs 0x30
gs 0x10
edi 0xc2a90938
esi 0xc2a9a000
ebp 0xcd3f2a5c
ebx 0
edx 0xcd427080
ecx 0xc311da50
eax 0x6d666900
eip 0xcd7179df
cs 0x8
eflags 0x10283
esp 0xcd3f2a34
ss 0x10
0xcd7179df: lodsl (%esi)
On FreeBSD it works and they use the following bus_space implementation:
static __inline void
bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
bus_size_t offset, const u_int32_t *addr, size_t
count)
{
if (tag == I386_BUS_SPACE_IO)
outsl(bsh + offset, addr, count);
else {
#ifdef __GNUCLIKE_ASM
__asm __volatile(" \n\
cld \n\
1: lodsl \n\
movl %%eax,(%2) \n\
loop 1b" :
"=S" (addr), "=c" (count) :
"r" (bsh + offset), "0" (addr), "1" (count) :
"%eax", "memory", "cc");
#else
# ifndef lint
# error "no assembler code for your compiler"
# endif
#endif
}
}
--HPS
Home |
Main Index |
Thread Index |
Old Index