Fall2009/GCC Hacking Exercise

From OpenSourceSoftwarePractice
Jump to: navigation, search

GCC Hacking Exercise

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 '