|
Message-ID: <20111017175612.GA15462@albatros> Date: Mon, 17 Oct 2011 21:56:12 +0400 From: Vasiliy Kulikov <segoon@...nwall.com> To: owl-dev@...ts.openwall.com Subject: gcc 4.6.1: glibc __sincos() issue Hi, After building gcc 4.6.1 and making glibc compilable there is one error. Groff's "pic" built with glibc built with gcc 4.6.1 calls __sincos and goes into infinite __sincos recursion: /usr/src/world/rpm-work-1/BUILD/groff-1.20.1/src/roff/groff/groff: pic: Signal 11 <standard input>:226: warning: closing delimiter does not match It is "pic pic.ms" command. If run it under gdb: $ bash -c 'ulimit -s 50; gdb -d ~/sources/Owl/packages/glibc/glibc-2.3.6/conf/ ../src/preproc/pic/pic' (gdb) run pic.ms [...pic's output skipped...] Program received signal SIGSEGV, Segmentation fault. __sincos (x=1.5707963267948966, sinx=0x7fffae3f0048, cosx=0x7fffae3f0040) at ../sysdeps/ieee754/dbl-64/s_sincos.c:32 32 GET_HIGH_WORD (ix, x); (gdb) info stack ... #20 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 #21 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 #22 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 #23 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 ... #33463 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 #33464 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 #33465 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 #33466 0x0000000000410dc0 in object_spec::make_arc () #33467 0x0000000000000000 in ?? () #33468 0x00002b2974c7d5e0 in _IO_2_1_stderr_ () from /lib64/libc.so.6 #33469 0x0000000000637dc0 in current_position () #33470 0x3fe921fb54442d18 in ?? () #33471 0x0000000000000078 in ?? () #33472 0x0000000000000040 in ?? () #33473 0x4016000000000000 in ?? () #33474 0x0000000000000000 in ?? () #33475 0x4017000000000000 in ?? () #33476 0x3fd0000000000000 in ?? () #33477 0x0000000000000000 in ?? () #33478 0x0000000000000000 in ?? () #33479 0x3fc0000000000000 in ?? () #33480 0x3fc0000000000000 in ?? () #33481 0x0000000001d25360 in ?? () #33482 0x0000000001d25360 in ?? () #33483 0x0000000000000040 in ?? () #33484 0x0000000000411f45 in object_spec::make_linear () #33485 0x000000000000003b in ?? () #33486 0x000000000041caf7 in string::operator= () (gdb) frame 33000 #33000 0x00002b29744e182e in __sincos (x=Variable "x" is not available.) at ../sysdeps/ieee754/dbl-64/s_sincos.c:39 39 *sinx = *cosx = x - x; (gdb) list 34 /* |x| ~< pi/4 */ 35 ix &= 0x7fffffff; 36 if (ix>=0x7ff00000) 37 { 38 /* sin(Inf or NaN) is NaN */ 39 *sinx = *cosx = x - x; 40 } 41 else 42 { 43 *sinx = sin (x); (0x00002b29744e182e doesn't match line 39 of the source file, see below.) (gdb) disassemble __sincos Dump of assembler code for function __sincos: 0x00002b29744e17f0 <__sincos+0>: mov %rbx,0xfffffffffffffff0(%rsp) 0x00002b29744e17f5 <__sincos+5>: mov %rbp,0xfffffffffffffff8(%rsp) 0x00002b29744e17fa <__sincos+10>: sub $0x38,%rsp 0x00002b29744e17fe <__sincos+14>: movsd %xmm0,0x8(%rsp) 0x00002b29744e1804 <__sincos+20>: mov 0x8(%rsp),%rax 0x00002b29744e1809 <__sincos+25>: mov %rdi,%rbp 0x00002b29744e180c <__sincos+28>: mov %rsi,%rbx 0x00002b29744e180f <__sincos+31>: shr $0x20,%rax 0x00002b29744e1813 <__sincos+35>: and $0x7fffffff,%eax 0x00002b29744e1818 <__sincos+40>: cmp $0x7fefffff,%eax 0x00002b29744e181d <__sincos+45>: jg 0x2b29744e1850 <__sincos+96> 0x00002b29744e181f <__sincos+47>: lea 0x10(%rsp),%rsi 0x00002b29744e1824 <__sincos+52>: lea 0x18(%rsp),%rdi 0x00002b29744e1829 <__sincos+57>: callq 0x2b29744bfcd0 <_init+40> 0x00002b29744e182e <__sincos+62>: mov 0x18(%rsp),%rax <---------------ret address 0x00002b29744e1833 <__sincos+67>: mov %rax,0x0(%rbp) 0x00002b29744e1837 <__sincos+71>: mov 0x10(%rsp),%rax 0x00002b29744e183c <__sincos+76>: mov 0x30(%rsp),%rbp 0x00002b29744e1841 <__sincos+81>: mov %rax,(%rbx) 0x00002b29744e1844 <__sincos+84>: mov 0x28(%rsp),%rbx 0x00002b29744e1849 <__sincos+89>: add $0x38,%rsp 0x00002b29744e184d <__sincos+93>: retq 0x00002b29744e184e <__sincos+94>: data16 0x00002b29744e184f <__sincos+95>: nop 0x00002b29744e1850 <__sincos+96>: subsd %xmm0,%xmm0 0x00002b29744e1854 <__sincos+100>: mov 0x28(%rsp),%rbx 0x00002b29744e1859 <__sincos+105>: mov 0x30(%rsp),%rbp 0x00002b29744e185e <__sincos+110>: movsd %xmm0,(%rsi) 0x00002b29744e1862 <__sincos+114>: movsd %xmm0,(%rdi) 0x00002b29744e1866 <__sincos+118>: add $0x38,%rsp 0x00002b29744e186a <__sincos+122>: retq End of assembler dump. (gdb) x/i 0x2b29744bfcd0 0x2b29744bfcd0 <_init+40>: jmpq *2601770(%rip) # 0x2b297473b000 <__JCR_LIST__+536> callq at _init+40 is a call to __sincos(). In the source file (./sysdeps/ieee754/dbl-64/s_sincos.c): void __sincos (double x, double *sinx, double *cosx) { int32_t ix; /* High word of x. */ GET_HIGH_WORD (ix, x); /* |x| ~< pi/4 */ ix &= 0x7fffffff; if (ix>=0x7ff00000) { /* sin(Inf or NaN) is NaN */ *sinx = *cosx = x - x; } else { *sinx = sin (x); *cosx = cos (x); } } weak_alias (__sincos, sincos) So, it is an optimised call to sin() and cos(), which is optimised to call to __sincos(). However, I cannot understand how it can happen as sin() and cos() are defined in ./sysdeps/ieee754/dbl-64/s_sin.c as following: double __cos(double x) { double y,xx,res,t,cor,s,c,sn,ssn,cs,ccs,xn,a,da,db,eps,xn1,xn2; mynumber u,v; int4 k,m,n; u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff&m; if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */ else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */ y=ABS(x); u.x = big.x+y; y = y-(u.x-big.x); xx=y*y; s = y + y*xx*(sn3 +xx*sn5); c = xx*(cs2 +xx*(cs4 + xx*cs6)); k=u.i[LOW_HALF]<<2; sn=sincos.x[k]; ssn=sincos.x[k+1]; cs=sincos.x[k+2]; ccs=sincos.x[k+3]; cor=(ccs-s*ssn-cs*c)-sn*s; res=cs+cor; cor=(cs-res)+cor; return (res==res+1.020*cor)? res : cslow2(x); } /* else if (k < 0x3feb6000) */ ... else return x / x; /* |x| > 2^1024 */ return 0; } weak_alias (__cos, cos) I see no call to __sincos() inside. It is the used version of cos() as removing this weak_alias() makes groff compilation fail with "undefined function: cos". As removing the latter weak_alias() makes cos() invisible, I cannot understand what makes __sincos() call itself. Any ideas? If it can help, I can post resulting libm/libc or .o files. Thanks, -- Vasiliy
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.