| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "courgette/rel32_finder_win32_x86.h" | 5 #include "courgette/rel32_finder_win32_x86.h" |
| 6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
| 7 #include <algorithm> | 10 #include <algorithm> |
| 8 #include <sstream> | 11 #include <sstream> |
| 9 #include <string> | 12 #include <string> |
| 10 | 13 |
| 11 #include "base/macros.h" | 14 #include "base/macros.h" |
| 12 #include "courgette/base_test_unittest.h" | 15 #include "courgette/base_test_unittest.h" |
| 13 #include "courgette/image_utils.h" | 16 #include "courgette/image_utils.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 18 |
| 16 namespace courgette { | 19 namespace courgette { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 40 EXPECT_EQ(expected_rel32_locations_, rel32_locations) | 43 EXPECT_EQ(expected_rel32_locations_, rel32_locations) |
| 41 << "From test case " << name << " (addresses are in hex)"; | 44 << "From test case " << name << " (addresses are in hex)"; |
| 42 } | 45 } |
| 43 | 46 |
| 44 private: | 47 private: |
| 45 RVA text_start_rva_; | 48 RVA text_start_rva_; |
| 46 RVA text_end_rva_; | 49 RVA text_end_rva_; |
| 47 RVA relocs_start_rva_; | 50 RVA relocs_start_rva_; |
| 48 RVA relocs_end_rva_; | 51 RVA relocs_end_rva_; |
| 49 RVA image_end_rva_; | 52 RVA image_end_rva_; |
| 50 std::vector<uint8> text_data_; | 53 std::vector<uint8_t> text_data_; |
| 51 std::vector<RVA> abs32_locations_; | 54 std::vector<RVA> abs32_locations_; |
| 52 std::vector<RVA> expected_rel32_locations_; | 55 std::vector<RVA> expected_rel32_locations_; |
| 53 | 56 |
| 54 // Scans |iss| for the next non-empty line, after removing "#"-style comments | 57 // Scans |iss| for the next non-empty line, after removing "#"-style comments |
| 55 // and stripping trailing spaces. On success, returns true and writes the | 58 // and stripping trailing spaces. On success, returns true and writes the |
| 56 // result to |line_out|. Otherwise returns false. | 59 // result to |line_out|. Otherwise returns false. |
| 57 bool ReadNonEmptyLine(std::istringstream& iss, std::string* line_out) { | 60 bool ReadNonEmptyLine(std::istringstream& iss, std::string* line_out) { |
| 58 std::string line; | 61 std::string line; |
| 59 while (std::getline(iss, line)) { | 62 while (std::getline(iss, line)) { |
| 60 // Trim comments and trailing spaces. | 63 // Trim comments and trailing spaces. |
| 61 size_t end_pos = std::min(line.find("#"), line.length()); | 64 size_t end_pos = std::min(line.find("#"), line.length()); |
| 62 while (end_pos > 0 && line[end_pos] == ' ') | 65 while (end_pos > 0 && line[end_pos] == ' ') |
| 63 --end_pos; | 66 --end_pos; |
| 64 line.resize(end_pos); | 67 line.resize(end_pos); |
| 65 if (!line.empty()) | 68 if (!line.empty()) |
| 66 break; | 69 break; |
| 67 } | 70 } |
| 68 if (line.empty()) | 71 if (line.empty()) |
| 69 return false; | 72 return false; |
| 70 line_out->swap(line); | 73 line_out->swap(line); |
| 71 return true; | 74 return true; |
| 72 } | 75 } |
| 73 | 76 |
| 74 // Scans |iss| for the next non-empty line, and reads (hex) uint32 into |v|. | 77 // Scans |iss| for the next non-empty line, and reads (hex) uint32_t into |v|. |
| 75 // Returns true iff successful. | 78 // Returns true iff successful. |
| 76 bool ReadHexUInt32(std::istringstream& iss, uint32* v) { | 79 bool ReadHexUInt32(std::istringstream& iss, uint32_t* v) { |
| 77 std::string line; | 80 std::string line; |
| 78 if (!ReadNonEmptyLine(iss, &line)) | 81 if (!ReadNonEmptyLine(iss, &line)) |
| 79 return false; | 82 return false; |
| 80 return sscanf(line.c_str(), "%X", v) == 1; | 83 return sscanf(line.c_str(), "%X", v) == 1; |
| 81 } | 84 } |
| 82 | 85 |
| 83 // Initializes the test case by parsing the multi-line string |test_data| | 86 // Initializes the test case by parsing the multi-line string |test_data| |
| 84 // to extract Rel32FinderWin32X86 parameters, and read expected values. | 87 // to extract Rel32FinderWin32X86 parameters, and read expected values. |
| 85 void LoadTestFromString(const std::string& test_data) { | 88 void LoadTestFromString(const std::string& test_data) { |
| 86 // The first lines (ignoring empty ones) specify RVA bounds. | 89 // The first lines (ignoring empty ones) specify RVA bounds. |
| 87 std::istringstream iss(test_data); | 90 std::istringstream iss(test_data); |
| 88 ASSERT_TRUE(ReadHexUInt32(iss, &text_start_rva_)); | 91 ASSERT_TRUE(ReadHexUInt32(iss, &text_start_rva_)); |
| 89 ASSERT_TRUE(ReadHexUInt32(iss, &text_end_rva_)); | 92 ASSERT_TRUE(ReadHexUInt32(iss, &text_end_rva_)); |
| 90 ASSERT_TRUE(ReadHexUInt32(iss, &relocs_start_rva_)); | 93 ASSERT_TRUE(ReadHexUInt32(iss, &relocs_start_rva_)); |
| 91 ASSERT_TRUE(ReadHexUInt32(iss, &relocs_end_rva_)); | 94 ASSERT_TRUE(ReadHexUInt32(iss, &relocs_end_rva_)); |
| 92 ASSERT_TRUE(ReadHexUInt32(iss, &image_end_rva_)); | 95 ASSERT_TRUE(ReadHexUInt32(iss, &image_end_rva_)); |
| 93 | 96 |
| 94 std::string line; | 97 std::string line; |
| 95 // The Program section specifies instruction bytes. We require lines to be | 98 // The Program section specifies instruction bytes. We require lines to be |
| 96 // formatted in "DUMPBIN /DISASM" style, i.e., | 99 // formatted in "DUMPBIN /DISASM" style, i.e., |
| 97 // "00401003: E8 00 00 00 00 call 00401008" | 100 // "00401003: E8 00 00 00 00 call 00401008" |
| 98 // ^ ^ ^ ^ ^ ^ | 101 // ^ ^ ^ ^ ^ ^ |
| 99 // We extract up to 6 bytes per line. The remaining are ignored. | 102 // We extract up to 6 bytes per line. The remaining are ignored. |
| 100 const int kBytesBegin = 12; | 103 const int kBytesBegin = 12; |
| 101 const int kBytesEnd = 17; | 104 const int kBytesEnd = 17; |
| 102 ReadNonEmptyLine(iss, &line); | 105 ReadNonEmptyLine(iss, &line); |
| 103 ASSERT_EQ("Program:", line); | 106 ASSERT_EQ("Program:", line); |
| 104 while (ReadNonEmptyLine(iss, &line) && line != "Abs32:") { | 107 while (ReadNonEmptyLine(iss, &line) && line != "Abs32:") { |
| 105 std::string toks = line.substr(kBytesBegin, kBytesEnd); | 108 std::string toks = line.substr(kBytesBegin, kBytesEnd); |
| 106 uint32 vals[6]; | 109 uint32_t vals[6]; |
| 107 int num_read = sscanf(toks.c_str(), "%X %X %X %X %X %X", &vals[0], | 110 int num_read = sscanf(toks.c_str(), "%X %X %X %X %X %X", &vals[0], |
| 108 &vals[1], &vals[2], &vals[3], &vals[4], &vals[5]); | 111 &vals[1], &vals[2], &vals[3], &vals[4], &vals[5]); |
| 109 for (int i = 0; i < num_read; ++i) | 112 for (int i = 0; i < num_read; ++i) |
| 110 text_data_.push_back(static_cast<uint8>(vals[i] & 0xFF)); | 113 text_data_.push_back(static_cast<uint8_t>(vals[i] & 0xFF)); |
| 111 } | 114 } |
| 112 ASSERT_FALSE(text_data_.empty()); | 115 ASSERT_FALSE(text_data_.empty()); |
| 113 | 116 |
| 114 // The Abs32 section specifies hex RVAs, one per line. | 117 // The Abs32 section specifies hex RVAs, one per line. |
| 115 ASSERT_EQ("Abs32:", line); | 118 ASSERT_EQ("Abs32:", line); |
| 116 while (ReadNonEmptyLine(iss, &line) && line != "Expected:") { | 119 while (ReadNonEmptyLine(iss, &line) && line != "Expected:") { |
| 117 RVA abs32_location; | 120 RVA abs32_location; |
| 118 ASSERT_EQ(1, sscanf(line.c_str(), "%X", &abs32_location)); | 121 ASSERT_EQ(1, sscanf(line.c_str(), "%X", &abs32_location)); |
| 119 abs32_locations_.push_back(abs32_location); | 122 abs32_locations_.push_back(abs32_location); |
| 120 } | 123 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 140 TEST_F(Rel32FinderWin32X86Test, TestBasic) { | 143 TEST_F(Rel32FinderWin32X86Test, TestBasic) { |
| 141 RunTest("rel32_win32_x86_01.txt"); | 144 RunTest("rel32_win32_x86_01.txt"); |
| 142 RunTest("rel32_win32_x86_02.txt"); | 145 RunTest("rel32_win32_x86_02.txt"); |
| 143 RunTest("rel32_win32_x86_03.txt"); | 146 RunTest("rel32_win32_x86_03.txt"); |
| 144 RunTest("rel32_win32_x86_04.txt"); | 147 RunTest("rel32_win32_x86_04.txt"); |
| 145 } | 148 } |
| 146 | 149 |
| 147 } // namespace | 150 } // namespace |
| 148 | 151 |
| 149 } // namespace courgette | 152 } // namespace courgette |
| OLD | NEW |