Home | History | Annotate | Download | only in courgette
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "courgette/assembly_program.h"
      6 #include "courgette/base_test_unittest.h"
      7 #include "courgette/disassembler_elf_32_x86.h"
      8 
      9 class DisassemblerElf32X86Test : public BaseTest {
     10  public:
     11 
     12   void TestExe(const char* file_name,
     13                size_t expected_abs_count,
     14                size_t expected_rel_count) const;
     15 };
     16 
     17 void DisassemblerElf32X86Test::TestExe(const char* file_name,
     18                                        size_t expected_abs_count,
     19                                        size_t expected_rel_count) const {
     20   std::string file1 = FileContents(file_name);
     21 
     22   scoped_ptr<courgette::DisassemblerElf32X86> disassembler(
     23       new courgette::DisassemblerElf32X86(file1.c_str(), file1.length()));
     24 
     25   bool can_parse_header = disassembler->ParseHeader();
     26   EXPECT_TRUE(can_parse_header);
     27   EXPECT_TRUE(disassembler->ok());
     28 
     29   // The length of the disassembled value will be slightly smaller than the
     30   // real file, since trailing debug info is not included
     31   EXPECT_EQ(file1.length(), disassembler->length());
     32 
     33   const uint8* offset_p = disassembler->OffsetToPointer(0);
     34   EXPECT_EQ(reinterpret_cast<const void*>(file1.c_str()),
     35             reinterpret_cast<const void*>(offset_p));
     36   EXPECT_EQ(0x7F, offset_p[0]);
     37   EXPECT_EQ('E', offset_p[1]);
     38   EXPECT_EQ('L', offset_p[2]);
     39   EXPECT_EQ('F', offset_p[3]);
     40 
     41   courgette::AssemblyProgram* program =
     42     new courgette::AssemblyProgram(courgette::EXE_ELF_32_X86);
     43 
     44   EXPECT_TRUE(disassembler->Disassemble(program));
     45 
     46   EXPECT_EQ(disassembler->Abs32Locations().size(), expected_abs_count);
     47   EXPECT_EQ(disassembler->Rel32Locations().size(), expected_rel_count);
     48 
     49   // Prove that none of the rel32 RVAs overlap with abs32 RVAs
     50   std::set<courgette::RVA> abs(disassembler->Abs32Locations().begin(),
     51                                disassembler->Abs32Locations().end());
     52   std::set<courgette::DisassemblerElf32::TypedRVA*>
     53     rel(disassembler->Rel32Locations().begin(),
     54         disassembler->Rel32Locations().end());
     55   for (std::vector<courgette::DisassemblerElf32::TypedRVA*>::iterator
     56          rel32 = disassembler->Rel32Locations().begin();
     57        rel32 !=  disassembler->Rel32Locations().end();
     58        rel32++) {
     59     EXPECT_TRUE(abs.find((*rel32)->rva()) == abs.end());
     60   }
     61 
     62   for (std::vector<courgette::RVA>::iterator abs32 =
     63         disassembler->Abs32Locations().begin();
     64        abs32 !=  disassembler->Abs32Locations().end();
     65        abs32++) {
     66     bool found = false;
     67     for (std::vector<courgette::DisassemblerElf32::TypedRVA*>::iterator
     68            rel32 = disassembler->Rel32Locations().begin();
     69          rel32 !=  disassembler->Rel32Locations().end();
     70          rel32++) {
     71       if (*abs32 == (*rel32)->rva()) {
     72         found = true;
     73         break;
     74       }
     75     }
     76     EXPECT_TRUE(!found);
     77   }
     78   delete program;
     79 }
     80 
     81 TEST_F(DisassemblerElf32X86Test, All) {
     82   TestExe("elf-32-1", 200, 3442);
     83 }
     84