Bug 24944 - gas doesn't read all necessary digits when parsing a floating point number
Summary: gas doesn't read all necessary digits when parsing a floating point number
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.33
: P2 normal
Target Milestone: 2.34
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-08-28 18:32 UTC by Bosco García
Modified: 2019-11-20 11:36 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed: 2019-11-20 00:00:00


Attachments
Patch for this bug (1.14 KB, patch)
2019-08-28 18:32 UTC, Bosco García
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bosco García 2019-08-28 18:32:14 UTC
Created attachment 11966 [details]
Patch for this bug

The pseudo instruction .double doesn't work fine parsing some numbers.
The function atof_generic doesn't read all digits of the number.

POC:
$ cat << EOF | as -o tmp && objdump -s tmp
.data
.double 37778931862957165903873.0
EOF

Output of previous command is:

tmp:     file format elf64-x86-64

Contents of section .data:
0000 00000000 0000a044                    .......D

We note that number N=37778931862957165903873.0 is calculated with bc with
command:

$echo 'e=75; 2^e + 2^(e-53) + 1' | bc

Then the numbers a=2^75 and b=(1+2^-52)*2^75 are the below and above
approximation of N to a double floating number. The output of previous
command shows that .double instruction chooses 2^75 as double aproximation,
although floating number (1+2^-52)*2^75 is closest to N since N=(a+b)/2 + 1.

This is due to a variable called ``maximum_useful_digits'' which limits the
number of read digits.

We can replace the variable ``maximum_useful_digits'' by the variable
``number_of_digits_available''.


gas/Changelog:
	* atof-generic.c: Delete the variable maximum_useful_digits.
	* testsuite/gas/i386/fp.s: add numbers where this bugs ocurrs.
	* testsuite/gas/i386/fp.d: correct output.
Comment 1 Alan Modra 2019-11-20 10:36:08 UTC
Doing away with the limit won't work if someone uses .double with more than 1292 digits, because the following multiplication will overflow:
      more_than_enough_bits_for_digits
	= (number_of_digits_to_use * 3321928 / 1000000 + 1);
Comment 2 Sourceware Commits 2019-11-20 11:35:03 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=94c9b9db4b689bc1ae643e053580db1fdfaee2d4

commit 94c9b9db4b689bc1ae643e053580db1fdfaee2d4
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Nov 20 21:54:07 2019 +1030

    PR24944, gas doesn't read enough digits when parsing a floating point number
    
    	PR 24944
    	* atof-generic.c (atof_generic): Increase decimal guard digits.
    	* testsuite/gas/i386/fp.s: Add more tests.
    	* testsuite/gas/i386/fp.d: Update.
Comment 3 Alan Modra 2019-11-20 11:36:17 UTC
Fixed.