TypeTest.cpp

Go to the documentation of this file.
00001 /*==============================================================================
00002  * FILE:       TypeTest.cc
00003  * OVERVIEW:   Provides the implementation for the TypeTest class, which tests the Type class and some utility functions
00004  *============================================================================*/
00005 /*
00006  * $Revision: 1.11 $
00007  *
00008  * 09 Apr 02 - Mike: Created
00009  * 22 Aug 03 - Mike: Extended for Constraint tests
00010  * 25 Juk 05 - Mike: DataIntervalMap tests
00011  */
00012 
00013 #define HELLO_WINDOWS       "test/windows/hello.exe"
00014 
00015 #include <iostream>
00016 #include "TypeTest.h"
00017 #include "BinaryFile.h"         // Ugh - needed before frontend.h
00018 #include "pentiumfrontend.h"
00019 #include "signature.h"
00020 #include "boomerang.h"
00021 #include "log.h"
00022 #include "prog.h"
00023 
00024 /*==============================================================================
00025  * FUNCTION:        TypeTest::registerTests
00026  * OVERVIEW:        Register the test functions in the given suite
00027  * PARAMETERS:      Pointer to the test suite
00028  * RETURNS:         <nothing>
00029  *============================================================================*/
00030 #define MYTEST(name) \
00031 suite->addTest(new CppUnit::TestCaller<TypeTest> ("Type", \
00032     &TypeTest::name, *this))
00033 
00034 void TypeTest::registerTests(CppUnit::TestSuite* suite) {
00035 
00036 //  Note: there is nothing left to test in Util (for now)
00037     MYTEST(testTypeLong);
00038     MYTEST(testNotEqual);
00039     MYTEST(testCompound);
00040     MYTEST(testDataInterval);
00041     MYTEST(testDataIntervalOverlaps);
00042 }
00043 
00044 int TypeTest::countTestCases () const
00045 { return 1; }   // ? What's this for?
00046 
00047 /*==============================================================================
00048  * FUNCTION:        TypeTest::setUp
00049  * OVERVIEW:        Set up anything needed before all tests
00050  * NOTE:            Called before any tests
00051  * PARAMETERS:      <none>
00052  * RETURNS:         <nothing>
00053  *============================================================================*/
00054 void TypeTest::setUp () {
00055 }
00056 
00057 /*==============================================================================
00058  * FUNCTION:        TypeTest::tearDown
00059  * OVERVIEW:        Delete objects created in setUp
00060  * NOTE:            Called after all tests
00061  * PARAMETERS:      <none>
00062  * RETURNS:         <nothing>
00063  *============================================================================*/
00064 void TypeTest::tearDown () {
00065 }
00066 
00067 /*==============================================================================
00068  * FUNCTION:        TypeTest::testTypeLong
00069  * OVERVIEW:        Test type unsigned long
00070  *============================================================================*/
00071 void TypeTest::testTypeLong () {
00072 
00073     std::string expected("unsigned long long");
00074     IntegerType t(64, -1);
00075     std::string actual(t.getCtype());
00076     CPPUNIT_ASSERT_EQUAL(expected, actual);
00077 }
00078 
00079 /*==============================================================================
00080  * FUNCTION:        TypeTest::testNotEqual
00081  * OVERVIEW:        Test type inequality
00082  *============================================================================*/
00083 void TypeTest::testNotEqual () {
00084 
00085     IntegerType t1(32, -1);
00086     IntegerType t2(32, -1);
00087     IntegerType t3(16, -1);
00088     CPPUNIT_ASSERT(!(t1 != t2));
00089     CPPUNIT_ASSERT(t2 != t3);
00090 }
00091 
00092 /*==============================================================================
00093  * FUNCTION:        TypeTest::testNotEqual
00094  * OVERVIEW:        Test type inequality
00095  *============================================================================*/
00096 void TypeTest::testCompound() {
00097     BinaryFileFactory bff;
00098     BinaryFile *pBF = bff.Load(HELLO_WINDOWS);
00099     FrontEnd *pFE = new PentiumFrontEnd(pBF, new Prog, &bff);
00100     Boomerang::get()->setLogger(new FileLogger());      // May try to output some messages to LOG
00101     pFE->readLibraryCatalog();              // Read definitions
00102 
00103     Signature* paintSig = pFE->getLibSignature("BeginPaint");
00104     // Second argument should be an LPPAINTSTRUCT
00105     Type* ty = paintSig->getParamType(1);
00106     const char* p = ty->getCtype();
00107     std::string expected("LPPAINTSTRUCT");
00108     std::string actual(p);
00109     CPPUNIT_ASSERT_EQUAL(expected, actual);
00110 
00111     // Get the type pointed to
00112     ty = ty->asPointer()->getPointsTo();
00113     p = ty->getCtype();
00114     expected = "PAINTSTRUCT";
00115     actual = p;
00116     CPPUNIT_ASSERT_EQUAL(expected, actual);
00117 
00118 
00119     // Offset 8 should have a RECT
00120     Type* subTy = ty->asCompound()->getTypeAtOffset(8*8);
00121     p = subTy->getCtype();
00122     expected = "RECT";
00123     actual = p;
00124     CPPUNIT_ASSERT_EQUAL(expected, actual);
00125 
00126     // Name at offset C should be bottom
00127     p = subTy->asCompound()->getNameAtOffset(0x0C*8);
00128     expected = "bottom";
00129     actual = p;
00130     CPPUNIT_ASSERT_EQUAL(expected, actual);
00131 
00132     // Now figure out the name at offset 8+C
00133     p = ty->asCompound()->getNameAtOffset((8 + 0x0C)*8);
00134     expected = "rcPaint";
00135     actual = p;
00136     CPPUNIT_ASSERT_EQUAL(expected, actual);
00137 
00138     // Also at offset 8
00139     p = ty->asCompound()->getNameAtOffset((8 + 0)*8);
00140     actual = p;
00141     CPPUNIT_ASSERT_EQUAL(expected, actual);
00142 
00143     // Also at offset 8+4
00144     p = ty->asCompound()->getNameAtOffset((8 + 4)*8);
00145     actual = p;
00146     CPPUNIT_ASSERT_EQUAL(expected, actual);
00147 
00148     // And at offset 8+8
00149     p = ty->asCompound()->getNameAtOffset((8 + 8)*8);
00150     actual = p;
00151     CPPUNIT_ASSERT_EQUAL(expected, actual);
00152 
00153     delete pFE;
00154 }
00155 
00156 /*==============================================================================
00157  * FUNCTION:        TypeTest::testDataInterval
00158  * OVERVIEW:        Test the DataIntervalMap class
00159  *============================================================================*/
00160 void TypeTest::testDataInterval() {
00161     DataIntervalMap dim;
00162     dim.addItem(0x1000, "first", new IntegerType(32, 1));
00163     dim.addItem(0x1004, "second", new FloatType(64));
00164     std::string actual(dim.prints());
00165     std::string expected("0x1000 first int\n"
00166         "0x1004 second double\n");
00167     CPPUNIT_ASSERT_EQUAL(expected, actual);
00168 
00169     DataIntervalEntry* pdie = dim.find(0x1000);
00170     expected = "first";
00171     CPPUNIT_ASSERT(pdie);
00172     actual = pdie->second.name;
00173     CPPUNIT_ASSERT_EQUAL(expected, actual);
00174 
00175     pdie = dim.find(0x1003);
00176     CPPUNIT_ASSERT(pdie);
00177     actual = pdie->second.name;
00178     CPPUNIT_ASSERT_EQUAL(expected, actual);
00179 
00180     pdie = dim.find(0x1004);
00181     CPPUNIT_ASSERT(pdie);
00182     expected = "second";
00183     actual = pdie->second.name;
00184     CPPUNIT_ASSERT_EQUAL(expected, actual);
00185     
00186     pdie = dim.find(0x1007);
00187     CPPUNIT_ASSERT(pdie);
00188     actual = pdie->second.name;
00189     CPPUNIT_ASSERT_EQUAL(expected, actual);
00190     
00191     CompoundType ct;
00192     ct.addType(new IntegerType(16, 1), "short1");
00193     ct.addType(new IntegerType(16, 1), "short2");
00194     ct.addType(new IntegerType(32, 1), "int1");
00195     ct.addType(new FloatType(32), "float1");
00196     dim.addItem(0x1010, "struct1", &ct);
00197 
00198     ComplexTypeCompList& ctcl = ct.compForAddress(0x1012, dim);
00199     unsigned ua = ctcl.size();
00200     unsigned ue = 1;
00201     CPPUNIT_ASSERT_EQUAL(ue, ua);
00202     ComplexTypeComp& ctc = ctcl.front();
00203     ue = 0;
00204     ua = ctc.isArray;
00205     CPPUNIT_ASSERT_EQUAL(ue, ua);
00206     expected = "short2";
00207     actual = ctc.u.memberName;
00208     CPPUNIT_ASSERT_EQUAL(expected, actual);
00209 
00210     // An array of 10 struct1's
00211     ArrayType at(&ct, 10);
00212     dim.addItem(0x1020, "array1", &at);
00213     ComplexTypeCompList& ctcl2 = at.compForAddress(0x1020+0x3C+8, dim);
00214     // Should be 2 components: [5] and .float1
00215     ue = 2;
00216     ua = ctcl2.size();
00217     CPPUNIT_ASSERT_EQUAL(ue, ua);
00218     ComplexTypeComp& ctc0 = ctcl2.front();
00219     ComplexTypeComp& ctc1 = ctcl2.back();
00220     ue = 1;
00221     ua = ctc0.isArray;
00222     CPPUNIT_ASSERT_EQUAL(ue, ua);
00223     ue = 5;
00224     ua = ctc0.u.index;
00225     CPPUNIT_ASSERT_EQUAL(ue, ua);
00226     ue = 0;
00227     ua = ctc1.isArray;
00228     CPPUNIT_ASSERT_EQUAL(ue, ua);
00229     expected = "float1";
00230     actual = ctc1.u.memberName;
00231     CPPUNIT_ASSERT_EQUAL(expected, actual);
00232 }
00233 
00234 /*==============================================================================
00235  * FUNCTION:        TypeTest::testDataIntervalOverlaps
00236  * OVERVIEW:        Test the DataIntervalMap class with overlapping addItems
00237  *============================================================================*/
00238 void TypeTest::testDataIntervalOverlaps() {
00239     DataIntervalMap dim;
00240     dim.addItem(0x1000, "firstInt", new IntegerType(32, 1));
00241     dim.addItem(0x1004, "firstFloat", new FloatType(32));
00242     dim.addItem(0x1008, "secondInt", new IntegerType(32, 1));
00243     dim.addItem(0x100C, "secondFloat", new FloatType(32));
00244     CompoundType ct;
00245     ct.addType(new IntegerType(32, 1), "int3");
00246     ct.addType(new FloatType(32), "float3");
00247     dim.addItem(0x1010, "existingStruct", &ct);
00248 
00249     // First insert a new struct over the top of the existing middle pair
00250     CompoundType ctu;
00251     ctu.addType(new IntegerType(32, 0), "newInt");      // This int has UNKNOWN sign
00252     ctu.addType(new FloatType(32), "newFloat");
00253     dim.addItem(0x1008, "replacementStruct", &ctu);
00254 
00255     DataIntervalEntry* pdie = dim.find(0x1008);
00256     std::string expected = "struct { int newInt; float newFloat; }";
00257     std::string actual = pdie->second.type->getCtype();
00258     CPPUNIT_ASSERT_EQUAL(expected, actual);
00259 
00260     // Attempt a weave; should fail
00261     CompoundType ct3;
00262     ct3.addType(new FloatType(32), "newFloat3");
00263     ct3.addType(new IntegerType(32, 0), "newInt3");
00264     dim.addItem(0x1004, "weaveStruct1", &ct3);
00265     pdie = dim.find(0x1004);
00266     expected = "firstFloat";
00267     actual = pdie->second.name;
00268     CPPUNIT_ASSERT_EQUAL(expected, actual);
00269 
00270     // Totally unaligned
00271     dim.addItem(0x1001, "weaveStruct2", &ct3);
00272     pdie = dim.find(0x1001);
00273     expected = "firstInt";
00274     actual = pdie->second.name;
00275     CPPUNIT_ASSERT_EQUAL(expected, actual);
00276 
00277     dim.addItem(0x1004, "firstInt", new IntegerType(32, 1));        // Should fail
00278     pdie = dim.find(0x1004);
00279     expected = "firstFloat";
00280     actual = pdie->second.name;
00281     CPPUNIT_ASSERT_EQUAL(expected, actual);
00282 
00283     // Set up three ints
00284     dim.deleteItem(0x1004);
00285     dim.addItem(0x1004, "firstInt", new IntegerType(32, 1));    // Definately signed
00286     dim.deleteItem(0x1008);
00287     dim.addItem(0x1008, "firstInt", new IntegerType(32, 0));    // Unknown signedess
00288     // then, add an array over the three integers
00289     ArrayType at(new IntegerType(32, 0), 3);
00290     dim.addItem(0x1000, "newArray", &at);
00291     pdie = dim.find(0x1005);                    // Check middle element
00292     expected = "newArray";
00293     actual = pdie->second.name;
00294     CPPUNIT_ASSERT_EQUAL(expected, actual);
00295     pdie = dim.find(0x1000);                    // Check first
00296     actual = pdie->second.name;
00297     CPPUNIT_ASSERT_EQUAL(expected, actual);
00298     pdie = dim.find(0x100B);                    // Check last
00299     actual = pdie->second.name;
00300     CPPUNIT_ASSERT_EQUAL(expected, actual);
00301 
00302     // Already have an array of 3 ints at 0x1000. Put a new array completely before, then with only one word overlap
00303     dim.addItem(0xF00, "newArray2", &at);
00304     pdie = dim.find(0x1000);                    // Shouyld still be newArray at 0x1000
00305     actual = pdie->second.name;
00306     CPPUNIT_ASSERT_EQUAL(expected, actual);
00307 
00308     pdie = dim.find(0xF00);
00309     expected = "newArray2";
00310     actual = pdie->second.name;
00311     CPPUNIT_ASSERT_EQUAL(expected, actual);
00312 
00313     dim.addItem(0xFF8, "newArray3", &at);       // Should fail
00314     pdie = dim.find(0xFF8);
00315     unsigned ue = 0;                            // Expect NULL
00316     unsigned ua = (unsigned)pdie;
00317     CPPUNIT_ASSERT_EQUAL(ue, ua);
00318 }

Generated on Tue Sep 19 21:18:35 2006 for Boomerang by  doxygen 1.4.6