NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Re: vfprintf() issue of printing negative float value
Dear christos,
Thanks for the quick reply, I have file the PR for the same.
The PR number is #44449
Please let us know if there are any issues.
Thank You,
Amol Pise
On Fri, 21 Jan 2011 14:08:36 +0530 wrote
>In article ,
nikunj badjatya wrote:
>Hi,
>
>I have found one issue in stdio module of NetBSD library while compiling it
>for
>ARMv7a (Cortex architecture) using the GNU GCC-4.5 toolchain.
>
>The issue is while printing negative float value and the float value
>greater than 9.0, vfprintf() prints malicious characters.
>
>This can be reproduce using the sample test as below:
>
>% Cat Sample_vfprintf.c
>{{{
>
>#include
>#include
>
>
>void format (FILE * stream, char * format, ...)
>{
> va_list args;
> va_start (args, format);
> vfprintf (stream, format, args);
> va_end (args);
>}
>
>
>int main ()
>{
> FILE * fp;
>
> fp = fopen ("myfile.txt","w");
> format (fp,"Call with %f \n",-3.14);
> format (fp,"Call with %f \n",10.0);
>
> fclose (fp);
> return 0;
>}
>
>}}}
>
>
>The output on beagleboard target is:
>{{{
>-bash-3.2# ./sample_vfprintf
>
>-bash-3.2# cat myfile.txt
>
>Call with 0.,0000
>Call with :.000000
>}}}
>
>>From the above sample it is seen that for negative float value and the float
>value
>greater than 9.0, vfprintf() prints malicious characters.
>
>Later, I modified the optimization flag from O2 to O1 and build the NetBsd
>library
>and found the issue is resolved.
>
>On these lines further I have analyzed and suspected this �wrong
>optimization� may be cause
>due to �strict aliasing�
>
>The man page of GNU GCC says about �strict aliasing�:
>
>�-fstrict-aliasing
> Allows the compiler to assume the strictest aliasing rules
>applicable to the language being compiled.
> For C (and C++), this activates optimizations based on the type of
>ex-pressions. In particular, an
> object of one type is assumed never to reside at the same address
>as an object of a different type,
> unless the types are almost the same. For example, an "unsigned
>int" can alias an "int", but not a
> "void*" or a "double". A character type may alias any other type.
>�
>
>
>To confirm this I have build NetBsd library using �-fno-strict-aliasing�
> flag with O2 optimization to suppress
>the �strict aliasing� and found the above issue is resolved.
>
>
>Further I have investigated it in the NetBsd source and found the flow of
>vfprintf as below:
>
> Vfprintf()
> ---> __vfprintf_unlocked
> ---> cvt()
> ---> __dtoa
>
>
>The dtoa() implementation in NetBsd as follows:
>
>$cat src/lib/libc/gdtoa/dtoa.c
>{{{
>
>148: if (word0(d) & Sign_bit) {
>149: /* set sign for everything, including 0's and NaNs */
>150: *sign = 1;
>151: word0(d) &= ~Sign_bit; /* clear sign bit */
>152: }
>
>}}}
>
>$cat src/lib/libc/gdtoa/gdtoaimp.h
>{{{
>176: #define ULong uint32_t
>:
>278:
>279: typedef union { double d; ULong L[2]; } U;
>:
>291: #ifdef IEEE_LITTLE_ENDIAN
>292: #define word0(x) ( /* LINTED */ (U*)&x)->L[1]
>293: #define word1(x) ( /* LINTED */ (U*)&x)->L[0]
>
>}}}
>
>
>
>Since at line:292 its breaking the strict aliasing rule. So, to bypass this
>Aliasing rules I used �__may_alias__� attribute as below.
>
>
>$cat src/lib/libc/gdtoa/gdtoaimp.h
>{{{
>- typedef union { double d; ULong L[2]; } U;
>+ typedef union { double d; ULong L[2]; } __attribute__((__may_alias__)) U;
>
>}}}
>
>With these changes vfprintf() is able to convert floating point number
>correctly without any issue.
>
>Please let me know if there are any issues.
>
Please file a PR...
Thanks,
christos
Home |
Main Index |
Thread Index |
Old Index