Fall2009/GCC Hacking Exercise
From OpenSourceSoftwarePractice
GCC Hacking Exercise
Contents |
Goal
De-mystifying GCC.
- It is Open
- You can study it
- You can change it
Task
Details:
Download GCC Source code
Download GCC source code from:
http://gcc.gnu.org/install/download.html
http://gcc.gnu.org/releases.html ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.3.2/
wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.3.2/gcc-core-4.3.2.tar.gz
110 seconds
wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.3.2/gcc-g++-4.3.2.tar.gz
23 seconds
Extracting the source code
tar -xzf gcc-g++-4.3.2.tar.gz
0.33s user 6.38s system 37% cpu 18.082 total
tar -xzf gcc-core-4.3.2.tar.gz
1.18s user 0.78s system 23% cpu 8.351 total
Pre-requsites
Installing prerequisites
http://gcc.gnu.org/install/prerequisites.html
sudo apt-get install libgmp3-dev
7 seconds
sudo apt-get install libmpfr-dev
8 seconds
Configuring
Of course, pick a different local directory for installation...
./configure --prefix=/home/ibanez/local/gcc-4.3.2
1.50s user 0.90s system 55% cpu 4.331 total
Compiling
make
1851.67s user 272.21s system 94% cpu 37:38.19 tota
make install
6.05s user 8.06s system 79% cpu 17.782 total
Testing Program
Test Program
What's wrong with this code ?
#include <iostream>
int main()
{
unsigned int p = 10;
double r = 5.0;
double d = - p * r;
std::cout << "d = " << d << std::endl;
return 0;
}
Run it
- Compile this program with the gcc that you just built.
install_dir/bin/g++ test.cxx
- Compile it with this warning flag:
install_dir/bin/g++ -Wsign-conversion test.cxx
- Run the program.
./a.out
- Check the casting problem, and its effect on the numeric result.
d = 2.14748e+10
Add Warning
add the following flag to the g++ call.
-Wsign-conversion
Patching GCC
Finding the file to modify
The file that requires a modification can be found by "grepping" for "sign-conversion", with a command similar to:
grep -r -l "sign-conversion" *
or by using "ack", with a command similar to:
ack-grep "sign-conversion"
among the resulting files you will see the file:
gcc-4.3.2/gcc/c-common.c
and if you open the file, and search for the string, you will eventually land in the function:
"conversion_warning"
/* Warns if the conversion of EXPR to TYPE may alter a value.
This is a helper function for warnings_for_convert_and_check. */
static void conversion_warning (tree type, tree expr) {...
Modifying the file
After you study the code, you will notice that lines 1220-1300 have a set of checks for different combinations of type conversions. Some of which refer to conversions from expressions to constants.
Once you get familiar with the code, you could go ahead and apply this patch
~/src/gcc/gcc-4.3.2/gcc 1229,1232d1228 < if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (TREE_TYPE (expr))) < warning (OPT_Wsign_conversion, < "RCOS:0001: Our friendly bug: 'conversion warning '"); <
Which means:
- Open the c-common.c file,
- Go to line 1228 and
- Insert the lines:
if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (TREE_TYPE (expr)))
warning (OPT_Wsign_conversion,
"RCOS:0001: Our friendly bug: 'conversion warning '");
- Compile GCC
make make install
- Recompile the test with this warning flag:
install_dir/bin/g++ -Wsign-conversion test.cxx
- Rerun the test example
- Verify that now you get the warning about the numeric conversion
You should now see a message similar to:
test.cxx: In function ‘int main()’: test.cxx:6: warning: RCOS:0001: Our friendly bug: 'conversion warning '
Second Testing Program
Try now this program:
#include <iostream>
int main()
{
unsigned int s = -10;
unsigned int t = -(10);
unsigned int p = 10;
double r = 5.0;
double d = - p * r;
std::cout << "d = " << d << std::endl;
return 0;
}
compile it with the same -Wsign-conversion flag.
You should now see a message similar to:
test2.cxx: In function ‘int main()’: test2.cxx:4: warning: negative integer implicitly converted to unsigned type test2.cxx:5: warning: negative integer implicitly converted to unsigned type test2.cxx:8: warning: RCOS:0001: Our friendly bug: 'conversion warning '
