15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "courgette/assembly_program.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "courgette/base_test_unittest.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "courgette/disassembler_elf_32_x86.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DisassemblerElf32X86Test : public BaseTest { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestExe(const char* file_name, 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_abs_count, 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_rel_count) const; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisassemblerElf32X86Test::TestExe(const char* file_name, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_abs_count, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_rel_count) const { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file1 = FileContents(file_name); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<courgette::DisassemblerElf32X86> disassembler( 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new courgette::DisassemblerElf32X86(file1.c_str(), file1.length())); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_parse_header = disassembler->ParseHeader(); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(can_parse_header); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(disassembler->ok()); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The length of the disassembled value will be slightly smaller than the 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // real file, since trailing debug info is not included 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(file1.length(), disassembler->length()); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* offset_p = disassembler->OffsetToPointer(0); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(reinterpret_cast<const void*>(file1.c_str()), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const void*>(offset_p)); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0x7F, offset_p[0]); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('E', offset_p[1]); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('L', offset_p[2]); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('F', offset_p[3]); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) courgette::AssemblyProgram* program = 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) new courgette::AssemblyProgram(courgette::EXE_ELF_32_X86); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(disassembler->Disassemble(program)); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(disassembler->Abs32Locations().size(), expected_abs_count); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(disassembler->Rel32Locations().size(), expected_rel_count); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prove that none of the rel32 RVAs overlap with abs32 RVAs 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<courgette::RVA> abs(disassembler->Abs32Locations().begin(), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disassembler->Abs32Locations().end()); 52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch std::set<courgette::DisassemblerElf32::TypedRVA*> 53a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch rel(disassembler->Rel32Locations().begin(), 54a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch disassembler->Rel32Locations().end()); 55a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for (std::vector<courgette::DisassemblerElf32::TypedRVA*>::iterator 56a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch rel32 = disassembler->Rel32Locations().begin(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rel32 != disassembler->Rel32Locations().end(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rel32++) { 59a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch EXPECT_TRUE(abs.find((*rel32)->rva()) == abs.end()); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<courgette::RVA>::iterator abs32 = 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disassembler->Abs32Locations().begin(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) abs32 != disassembler->Abs32Locations().end(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) abs32++) { 66a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch bool found = false; 67a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for (std::vector<courgette::DisassemblerElf32::TypedRVA*>::iterator 68a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch rel32 = disassembler->Rel32Locations().begin(); 69a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch rel32 != disassembler->Rel32Locations().end(); 70a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch rel32++) { 71a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (*abs32 == (*rel32)->rva()) { 72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch found = true; 73a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch break; 74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch EXPECT_TRUE(!found); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete program; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DisassemblerElf32X86Test, All) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestExe("elf-32-1", 200, 3442); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 84