blob: ddbb685a2dffcd837e60fe52a4e2d7541abc7ddc [file] [log] [blame]
Samuel Huang06f1ae92018-03-13 18:19:34 +00001// Copyright 2017 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 "components/zucchini/abs32_utils.h"
6
7#include <stdint.h>
8
9#include <algorithm>
10#include <string>
11#include <utility>
12
13#include "base/numerics/safe_conversions.h"
Samuel Huang98dd0172018-10-10 15:48:10 +000014#include "components/zucchini/address_translator.h"
Samuel Huang06f1ae92018-03-13 18:19:34 +000015#include "components/zucchini/image_utils.h"
16#include "components/zucchini/test_utils.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19namespace zucchini {
20
21namespace {
22
23// A trivial AddressTranslator that applies constant shift.
24class TestAddressTranslator : public AddressTranslator {
25 public:
26 TestAddressTranslator(size_t image_size, rva_t rva_begin) {
27 DCHECK_GE(rva_begin, 0U);
28 CHECK_EQ(AddressTranslator::kSuccess,
29 Initialize({{0, base::checked_cast<offset_t>(image_size),
30 rva_begin, base::checked_cast<rva_t>(image_size)}}));
31 }
32};
33
34// Helper to translate address |value| to RVA. May return |kInvalidRva|.
35rva_t AddrValueToRva(uint64_t value, AbsoluteAddress* addr) {
36 *addr->mutable_value() = value;
37 return addr->ToRva();
38}
39
40} // namespace
41
42TEST(Abs32UtilsTest, AbsoluteAddress32) {
43 std::vector<uint8_t> data32 = ParseHexString(
44 "00 00 32 00 21 43 65 4A 00 00 00 00 FF FF FF FF FF FF 31 00");
45 ConstBufferView image32(data32.data(), data32.size());
46 MutableBufferView mutable_image32(data32.data(), data32.size());
47
48 AbsoluteAddress addr32(kBit32, 0x00320000U);
49 EXPECT_TRUE(addr32.Read(0x0U, image32));
50 EXPECT_EQ(0x00000000U, addr32.ToRva());
51 EXPECT_TRUE(addr32.Read(0x4U, image32));
52 EXPECT_EQ(0x4A334321U, addr32.ToRva());
53 EXPECT_TRUE(addr32.Read(0x8U, image32));
54 EXPECT_EQ(kInvalidRva, addr32.ToRva()); // Underflow.
55 EXPECT_TRUE(addr32.Read(0xCU, image32));
Samuel Huang98dd0172018-10-10 15:48:10 +000056 EXPECT_EQ(kInvalidRva, addr32.ToRva()); // Translated RVA would be too large.
Samuel Huang06f1ae92018-03-13 18:19:34 +000057 EXPECT_TRUE(addr32.Read(0x10U, image32));
58 EXPECT_EQ(kInvalidRva, addr32.ToRva()); // Underflow (boundary case).
59
60 EXPECT_FALSE(addr32.Read(0x11U, image32));
61 EXPECT_FALSE(addr32.Read(0x14U, image32));
62 EXPECT_FALSE(addr32.Read(0x100000U, image32));
63 EXPECT_FALSE(addr32.Read(0x80000000U, image32));
64 EXPECT_FALSE(addr32.Read(0xFFFFFFFFU, image32));
65
66 EXPECT_TRUE(addr32.FromRva(0x11223344U));
67 EXPECT_TRUE(addr32.Write(0x2U, &mutable_image32));
68 EXPECT_TRUE(addr32.Write(0x10U, &mutable_image32));
69 std::vector<uint8_t> expected_data32 = ParseHexString(
70 "00 00 44 33 54 11 65 4A 00 00 00 00 FF FF FF FF 44 33 54 11");
71 EXPECT_EQ(expected_data32, data32);
72 EXPECT_FALSE(addr32.Write(0x11U, &mutable_image32));
73 EXPECT_FALSE(addr32.Write(0xFFFFFFFFU, &mutable_image32));
74 EXPECT_EQ(expected_data32, data32);
75}
76
77TEST(Abs32UtilsTest, AbsoluteAddress32Overflow) {
78 AbsoluteAddress addr32(kBit32, 0xC0000000U);
79 EXPECT_TRUE(addr32.FromRva(0x00000000U));
80 EXPECT_TRUE(addr32.FromRva(0x11223344U));
81 EXPECT_TRUE(addr32.FromRva(0x3FFFFFFFU));
82 EXPECT_FALSE(addr32.FromRva(0x40000000U));
83 EXPECT_FALSE(addr32.FromRva(0x40000001U));
84 EXPECT_FALSE(addr32.FromRva(0x80000000U));
85 EXPECT_FALSE(addr32.FromRva(0xFFFFFFFFU));
86
87 EXPECT_EQ(0x00000000U, AddrValueToRva(0xC0000000U, &addr32));
88 EXPECT_EQ(kInvalidRva, AddrValueToRva(0xBFFFFFFFU, &addr32));
89 EXPECT_EQ(kInvalidRva, AddrValueToRva(0x00000000U, &addr32));
90 EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xFFFFFFFFU, &addr32));
91}
92
93TEST(Abs32UtilsTest, AbsoluteAddress64) {
94 std::vector<uint8_t> data64 = ParseHexString(
95 "00 00 00 00 64 00 00 00 21 43 65 4A 64 00 00 00 "
96 "00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF "
97 "00 00 00 00 64 00 00 80 FF FF FF FF 63 00 00 00");
98 ConstBufferView image64(data64.data(), data64.size());
99 MutableBufferView mutable_image64(data64.data(), data64.size());
100
101 AbsoluteAddress addr64(kBit64, 0x0000006400000000ULL);
102 EXPECT_TRUE(addr64.Read(0x0U, image64));
103 EXPECT_EQ(0x00000000U, addr64.ToRva());
104 EXPECT_TRUE(addr64.Read(0x8U, image64));
105 EXPECT_EQ(0x4A654321U, addr64.ToRva());
106 EXPECT_TRUE(addr64.Read(0x10U, image64)); // Succeeds, in spite of value.
107 EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Underflow.
108 EXPECT_TRUE(addr64.Read(0x18U, image64));
109 EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Translated RVA too large.
110 EXPECT_TRUE(addr64.Read(0x20U, image64));
111 EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Translated RVA toolarge.
112 EXPECT_TRUE(addr64.Read(0x28U, image64));
113 EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Underflow.
114
115 EXPECT_FALSE(addr64.Read(0x29U, image64)); // Extends outside.
116 EXPECT_FALSE(addr64.Read(0x30U, image64)); // Entirely outside (note: hex).
117 EXPECT_FALSE(addr64.Read(0x100000U, image64));
118 EXPECT_FALSE(addr64.Read(0x80000000U, image64));
119 EXPECT_FALSE(addr64.Read(0xFFFFFFFFU, image64));
120
121 EXPECT_TRUE(addr64.FromRva(0x11223344U));
122 EXPECT_TRUE(addr64.Write(0x13U, &mutable_image64));
123 EXPECT_TRUE(addr64.Write(0x20U, &mutable_image64));
124 std::vector<uint8_t> expected_data64 = ParseHexString(
125 "00 00 00 00 64 00 00 00 21 43 65 4A 64 00 00 00 "
126 "00 00 00 44 33 22 11 64 00 00 00 FF FF FF FF FF "
127 "44 33 22 11 64 00 00 00 FF FF FF FF 63 00 00 00");
128 EXPECT_EQ(expected_data64, data64);
129 EXPECT_FALSE(addr64.Write(0x29U, &mutable_image64));
130 EXPECT_FALSE(addr64.Write(0x30U, &mutable_image64));
131 EXPECT_FALSE(addr64.Write(0xFFFFFFFFU, &mutable_image64));
132 EXPECT_EQ(expected_data64, data64);
133
134 EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFU));
135}
136
137TEST(Abs32UtilsTest, AbsoluteAddress64Overflow) {
138 {
139 // Counterpart to AbsoluteAddress632verflow test.
140 AbsoluteAddress addr64(kBit64, 0xFFFFFFFFC0000000ULL);
141 EXPECT_TRUE(addr64.FromRva(0x00000000U));
142 EXPECT_TRUE(addr64.FromRva(0x11223344U));
143 EXPECT_TRUE(addr64.FromRva(0x3FFFFFFFU));
144 EXPECT_FALSE(addr64.FromRva(0x40000000U));
145 EXPECT_FALSE(addr64.FromRva(0x40000001U));
146 EXPECT_FALSE(addr64.FromRva(0x80000000U));
147 EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFU));
148
149 EXPECT_EQ(0x00000000U, AddrValueToRva(0xFFFFFFFFC0000000U, &addr64));
150 EXPECT_EQ(kInvalidRva, AddrValueToRva(0xFFFFFFFFBFFFFFFFU, &addr64));
151 EXPECT_EQ(kInvalidRva, AddrValueToRva(0x0000000000000000U, &addr64));
152 EXPECT_EQ(kInvalidRva, AddrValueToRva(0xFFFFFFFF00000000U, &addr64));
153 EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xFFFFFFFFFFFFFFFFU, &addr64));
154 }
155 {
156 // Pseudo-counterpart to AbsoluteAddress632verflow test: Some now pass.
157 AbsoluteAddress addr64(kBit64, 0xC0000000U);
158 EXPECT_TRUE(addr64.FromRva(0x00000000U));
159 EXPECT_TRUE(addr64.FromRva(0x11223344U));
160 EXPECT_TRUE(addr64.FromRva(0x3FFFFFFFU));
161 EXPECT_TRUE(addr64.FromRva(0x40000000U));
162 EXPECT_TRUE(addr64.FromRva(0x40000001U));
163 EXPECT_FALSE(addr64.FromRva(0x80000000U));
164 EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFU));
165
166 // ToRva() still fail though.
167 EXPECT_EQ(0x00000000U, AddrValueToRva(0xC0000000U, &addr64));
168 EXPECT_EQ(kInvalidRva, AddrValueToRva(0xBFFFFFFFU, &addr64));
169 EXPECT_EQ(kInvalidRva, AddrValueToRva(0x00000000U, &addr64));
170 EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xFFFFFFFFU, &addr64));
171 }
172 {
173 AbsoluteAddress addr64(kBit64, 0xC000000000000000ULL);
174 EXPECT_TRUE(addr64.FromRva(0x00000000ULL));
175 EXPECT_TRUE(addr64.FromRva(0x11223344ULL));
176 EXPECT_TRUE(addr64.FromRva(0x3FFFFFFFULL));
177 EXPECT_TRUE(addr64.FromRva(0x40000000ULL));
178 EXPECT_TRUE(addr64.FromRva(0x40000001ULL));
179 EXPECT_FALSE(addr64.FromRva(0x80000000ULL));
180 EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFULL));
181
182 EXPECT_EQ(0x00000000U, AddrValueToRva(0xC000000000000000ULL, &addr64));
183 EXPECT_EQ(kInvalidRva, AddrValueToRva(0xBFFFFFFFFFFFFFFFULL, &addr64));
184 EXPECT_EQ(kInvalidRva, AddrValueToRva(0x0000000000000000ULL, &addr64));
185 EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xC00000003FFFFFFFULL, &addr64));
186 EXPECT_EQ(kInvalidRva, AddrValueToRva(0xFFFFFFFFFFFFFFFFULL, &addr64));
187 }
188}
189
190TEST(Abs32UtilsTest, Win32Read32) {
191 constexpr uint32_t kImageBase = 0xA0000000U;
192 constexpr uint32_t kRvaBegin = 0x00C00000U;
193 struct {
194 std::vector<uint8_t> data32;
195 std::vector<offset_t> abs32_locations; // Assumtion: Sorted.
196 offset_t lo; // Assumption: In range, does not straddle |abs32_location|.
197 offset_t hi; // Assumption: Also >= |lo|.
198 std::vector<Reference> expected_refs;
199 } test_cases[] = {
200 // Targets at beginning and end.
201 {ParseHexString("FF FF FF FF 0F 00 C0 A0 00 00 C0 A0 FF FF FF FF"),
202 {0x4U, 0x8U},
203 0x0U,
204 0x10U,
205 {{0x4U, 0xFU}, {0x8U, 0x0U}}},
206 // Targets at beginning and end are out of bound: Rejected.
207 {ParseHexString("FF FF FF FF 10 00 C0 A0 FF FF BF A0 FF FF FF FF"),
208 {0x4U, 0x8U},
209 0x0U,
210 0x10U,
211 std::vector<Reference>()},
212 // Same with more extreme target values: Rejected.
213 {ParseHexString("FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF"),
214 {0x4U, 0x8U},
215 0x0U,
216 0x10U,
217 std::vector<Reference>()},
218 // Locations at beginning and end, plus invalid locations.
219 {ParseHexString("08 00 C0 A0 FF FF FF FF FF FF FF FF 04 00 C0 A0"),
220 {0x0U, 0xCU, 0x10U, 0x1000U, 0x80000000U, 0xFFFFFFFFU},
221 0x0U,
222 0x10U,
223 {{0x0U, 0x8U}, {0xCU, 0x4U}}},
224 // Odd size, location, target.
225 {ParseHexString("FF FF FF 09 00 C0 A0 FF FF FF FF FF FF FF FF FF "
226 "FF FF FF"),
227 {0x3U},
228 0x0U,
229 0x13U,
230 {{0x3U, 0x9U}}},
231 // No location given.
232 {ParseHexString("FF FF FF FF 0C 00 C0 A0 00 00 C0 A0 FF FF FF FF"),
233 std::vector<offset_t>(), 0x0U, 0x10U, std::vector<Reference>()},
234 // Simple alternation.
235 {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
236 "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
237 {0x0U, 0x8U, 0x10U, 0x18U},
238 0x0U,
239 0x20U,
240 {{0x0U, 0x4U}, {0x8U, 0xCU}, {0x10U, 0x14U}, {0x18U, 0x1CU}}},
241 // Same, with locations limited by |lo| and |hi|. By assumption these must
242 // not cut accross Reference body.
243 {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
244 "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
245 {0x0U, 0x8U, 0x10U, 0x18U},
246 0x04U,
247 0x17U,
248 {{0x8U, 0xCU}, {0x10U, 0x14U}}},
249 // Same, with very limiting |lo| and |hi|.
250 {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
251 "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
252 {0x0U, 0x8U, 0x10U, 0x18U},
253 0x0CU,
254 0x10U,
255 std::vector<Reference>()},
256 // Same, |lo| == |hi|.
257 {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
258 "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
259 {0x0U, 0x8U, 0x10U, 0x18U},
260 0x14U,
261 0x14U,
262 std::vector<Reference>()},
263 // Same, |lo| and |hi| at end.
264 {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
265 "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
266 {0x0U, 0x8U, 0x10U, 0x18U},
267 0x20U,
268 0x20U,
269 std::vector<Reference>()},
270 // Mix. Note that targets can overlap.
271 {ParseHexString("FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF "
272 "06 00 C0 A0 2C 00 C0 A0 FF FF C0 A0 2B 00 C0 A0 "
273 "FF 06 00 C0 A0 00 00 C0 A0 FF FF FF FF FF FF FF"),
274 {0x10U, 0x14U, 0x18U, 0x1CU, 0x21U, 0x25U, 0xAAAAU},
275 0x07U,
276 0x25U,
277 {{0x10U, 0x6U}, {0x14U, 0x2CU}, {0x1CU, 0x2BU}, {0x21, 0x6U}}},
278 };
279
280 for (const auto& test_case : test_cases) {
281 ConstBufferView image32(test_case.data32.data(), test_case.data32.size());
282 Abs32RvaExtractorWin32 extractor(image32, {kBit32, kImageBase},
283 test_case.abs32_locations, test_case.lo,
284 test_case.hi);
285
286 TestAddressTranslator translator(test_case.data32.size(), kRvaBegin);
287 Abs32ReaderWin32 reader(std::move(extractor), translator);
288
289 // Loop over |expected_ref| to check element-by-element.
Anton Bikineev1a965512021-05-15 22:35:36 +0000290 absl::optional<Reference> ref;
Samuel Huang06f1ae92018-03-13 18:19:34 +0000291 for (const auto& expected_ref : test_case.expected_refs) {
292 ref = reader.GetNext();
293 EXPECT_TRUE(ref.has_value());
294 EXPECT_EQ(expected_ref, ref.value());
295 }
296 // Check that nothing is left.
297 ref = reader.GetNext();
298 EXPECT_FALSE(ref.has_value());
299 }
300}
301
302TEST(Abs32UtilsTest, Win32Read64) {
303 constexpr uint64_t kImageBase = 0x31415926A0000000U;
304 constexpr uint32_t kRvaBegin = 0x00C00000U;
305 // For simplicity, just test mixed case.
306 std::vector<uint8_t> data64 = ParseHexString(
307 "FF FF FF FF FF FF FF FF 00 00 C0 A0 26 59 41 31 "
308 "06 00 C0 A0 26 59 41 31 02 00 C0 A0 26 59 41 31 "
309 "FF FF FF BF 26 59 41 31 FF FF FF FF FF FF FF FF "
310 "02 00 C0 A0 26 59 41 31 07 00 C0 A0 26 59 41 31");
311 std::vector<offset_t> abs32_locations = {0x8U, 0x10U, 0x18U, 0x20U,
312 0x28U, 0x30U, 0x38U, 0x40U};
313 offset_t lo = 0x10U;
314 offset_t hi = 0x38U;
315 std::vector<Reference> expected_refs = {
316 {0x10U, 0x06U}, {0x18U, 0x02U}, {0x30U, 0x02U}};
317
318 ConstBufferView image64(data64.data(), data64.size());
319 Abs32RvaExtractorWin32 extractor(image64, {kBit64, kImageBase},
320 abs32_locations, lo, hi);
321 TestAddressTranslator translator(data64.size(), kRvaBegin);
322 Abs32ReaderWin32 reader(std::move(extractor), translator);
323
324 std::vector<Reference> refs;
Anton Bikineev1a965512021-05-15 22:35:36 +0000325 absl::optional<Reference> ref;
Samuel Huang06f1ae92018-03-13 18:19:34 +0000326 for (ref = reader.GetNext(); ref.has_value(); ref = reader.GetNext())
327 refs.push_back(ref.value());
328 EXPECT_EQ(expected_refs, refs);
329}
330
331TEST(Abs32UtilsTest, Win32ReadFail) {
332 // Make |bitness| a state to reduce repetition.
333 Bitness bitness = kBit32;
334
335 constexpr uint32_t kImageBase = 0xA0000000U; // Shared for 32-bit and 64-bit.
336 std::vector<uint8_t> data(32U, 0xFFU);
337 ConstBufferView image(data.data(), data.size());
338
339 auto try_make = [&](std::vector<offset_t>&& abs32_locations, offset_t lo,
340 offset_t hi) {
341 Abs32RvaExtractorWin32 extractor(image, {bitness, kImageBase},
342 abs32_locations, lo, hi);
343 extractor.GetNext(); // Dummy call so |extractor| gets used.
344 };
345
346 // 32-bit tests.
347 bitness = kBit32;
348 try_make({8U, 24U}, 0U, 32U);
349 EXPECT_DEATH(try_make({4U, 24U}, 32U, 0U), ""); // |lo| > |hi|.
350 try_make({8U, 24U}, 0U, 12U);
351 try_make({8U, 24U}, 0U, 28U);
352 try_make({8U, 24U}, 8U, 32U);
353 try_make({8U, 24U}, 24U, 32U);
354 EXPECT_DEATH(try_make({8U, 24U}, 0U, 11U), ""); // |hi| straddles.
355 EXPECT_DEATH(try_make({8U, 24U}, 26U, 32U), ""); // |lo| straddles.
356 try_make({8U, 24U}, 12U, 24U);
357
358 // 64-bit tests.
359 bitness = kBit64;
360 try_make({6U, 22U}, 0U, 32U);
361 // |lo| > |hi|.
362 EXPECT_DEATH(try_make(std::vector<offset_t>(), 32U, 31U), "");
363 try_make({6U, 22U}, 0U, 14U);
364 try_make({6U, 22U}, 0U, 30U);
365 try_make({6U, 22U}, 6U, 32U);
366 try_make({6U, 22U}, 22U, 32U);
367 EXPECT_DEATH(try_make({6U, 22U}, 0U, 29U), ""); // |hi| straddles.
368 EXPECT_DEATH(try_make({6U, 22U}, 7U, 32U), ""); // |lo| straddles.
369 try_make({6U, 22U}, 14U, 20U);
370 try_make({16U}, 16U, 24U);
371 EXPECT_DEATH(try_make({16U}, 18U, 18U), ""); // |lo|, |hi| straddle.
372}
373
374TEST(Abs32UtilsTest, Win32Write32) {
375 constexpr uint32_t kImageBase = 0xA0000000U;
376 constexpr uint32_t kRvaBegin = 0x00C00000U;
377 std::vector<uint8_t> data32(0x30, 0xFFU);
378 MutableBufferView image32(data32.data(), data32.size());
379 AbsoluteAddress addr(kBit32, kImageBase);
380 TestAddressTranslator translator(data32.size(), kRvaBegin);
381 Abs32WriterWin32 writer(image32, std::move(addr), translator);
382
383 // Successful writes.
384 writer.PutNext({0x02U, 0x10U});
385 writer.PutNext({0x0BU, 0x21U});
386 writer.PutNext({0x16U, 0x10U});
387 writer.PutNext({0x2CU, 0x00U});
388
389 // Invalid data: For simplicity, Abs32WriterWin32 simply ignores bad writes.
390 // Invalid location.
391 writer.PutNext({0x2DU, 0x20U});
392 writer.PutNext({0x80000000U, 0x20U});
393 writer.PutNext({0xFFFFFFFFU, 0x20U});
394 // Invalid target.
395 writer.PutNext({0x1CU, 0x00001111U});
396 writer.PutNext({0x10U, 0xFFFFFF00U});
397
398 std::vector<uint8_t> expected_data32 = ParseHexString(
399 "FF FF 10 00 C0 A0 FF FF FF FF FF 21 00 C0 A0 FF "
400 "FF FF FF FF FF FF 10 00 C0 A0 FF FF FF FF FF FF "
401 "FF FF FF FF FF FF FF FF FF FF FF FF 00 00 C0 A0");
402 EXPECT_EQ(expected_data32, data32);
403}
404
405TEST(Abs32UtilsTest, Win32Write64) {
406 constexpr uint64_t kImageBase = 0x31415926A0000000U;
407 constexpr uint32_t kRvaBegin = 0x00C00000U;
408 std::vector<uint8_t> data64(0x30, 0xFFU);
409 MutableBufferView image32(data64.data(), data64.size());
410 AbsoluteAddress addr(kBit64, kImageBase);
411 TestAddressTranslator translator(data64.size(), kRvaBegin);
412 Abs32WriterWin32 writer(image32, std::move(addr), translator);
413
414 // Successful writes.
415 writer.PutNext({0x02U, 0x10U});
416 writer.PutNext({0x0BU, 0x21U});
417 writer.PutNext({0x16U, 0x10U});
418 writer.PutNext({0x28U, 0x00U});
419
420 // Invalid data: For simplicity, Abs32WriterWin32 simply ignores bad writes.
421 // Invalid location.
422 writer.PutNext({0x29U, 0x20U});
423 writer.PutNext({0x80000000U, 0x20U});
424 writer.PutNext({0xFFFFFFFFU, 0x20U});
425 // Invalid target.
426 writer.PutNext({0x1CU, 0x00001111U});
427 writer.PutNext({0x10U, 0xFFFFFF00U});
428
429 std::vector<uint8_t> expected_data64 = ParseHexString(
430 "FF FF 10 00 C0 A0 26 59 41 31 FF 21 00 C0 A0 26 "
431 "59 41 31 FF FF FF 10 00 C0 A0 26 59 41 31 FF FF "
432 "FF FF FF FF FF FF FF FF 00 00 C0 A0 26 59 41 31");
433 EXPECT_EQ(expected_data64, data64);
434}
435
Samuel Huang98dd0172018-10-10 15:48:10 +0000436TEST(Abs32UtilsTest, RemoveUntranslatableAbs32) {
437 Bitness kBitness = kBit32;
438 uint64_t kImageBase = 0x2BCD0000;
439
440 // Valid RVAs: [0x00001A00, 0x00001A28) and [0x00003A00, 0x00004000).
441 // Valid AVAs: [0x2BCD1A00, 0x2BCD1A28) and [0x2BCD3A00, 0x2BCD4000).
442 // Notice that the second section has has dangling RVA.
443 AddressTranslator translator;
444 ASSERT_EQ(AddressTranslator::kSuccess,
445 translator.Initialize(
446 {{0x04, +0x28, 0x1A00, +0x28}, {0x30, +0x30, 0x3A00, +0x600}}));
447
448 std::vector<uint8_t> data = ParseHexString(
449 "FF FF FF FF 0B 3A CD 2B 00 00 00 04 3A CD 2B 00 "
450 "FC 3F CD 2B 14 1A CD 2B 44 00 00 00 CC 00 00 00 "
451 "00 00 55 00 00 00 1E 1A CD 2B 00 99 FF FF FF FF "
452 "10 3A CD 2B 22 00 00 00 00 00 00 11 00 00 00 00 "
453 "66 00 00 00 28 1A CD 2B 00 00 CD 2B 27 1A CD 2B "
454 "FF 39 CD 2B 00 00 00 00 18 1A CD 2B 00 00 00 00 "
455 "FF FF FF FF FF FF FF FF");
456 MutableBufferView image(data.data(), data.size());
457
458 const offset_t kAbs1 = 0x04; // a:2BCD3A0B = r:3A0B = o:3B
459 const offset_t kAbs2 = 0x0B; // a:2BCD3A04 = r:3A04 = o:34
460 const offset_t kAbs3 = 0x10; // a:2BCD3FFF = r:3FFF (dangling)
461 const offset_t kAbs4 = 0x14; // a:2BCD1A14 = r:1A14 = o:18
462 const offset_t kAbs5 = 0x26; // a:2BCD1A1E = r:1A1E = o:22
463 const offset_t kAbs6 = 0x30; // a:2BCD3A10 = r:3A10 = 0x40
464 const offset_t kAbs7 = 0x44; // a:2BCD1A28 = r:1A28 (bad: sentinel)
465 const offset_t kAbs8 = 0x48; // a:2BCD0000 = r:0000 (bad: not covered)
466 const offset_t kAbs9 = 0x4C; // a:2BCD1A27 = r:1A27 = 0x2B
467 const offset_t kAbsA = 0x50; // a:2BCD39FF (bad: not covered)
468 const offset_t kAbsB = 0x54; // a:00000000 (bad: underflow)
469 const offset_t kAbsC = 0x58; // a:2BCD1A18 = r:1A18 = 0x1C
470
471 std::vector<offset_t> locations = {kAbs1, kAbs2, kAbs3, kAbs4, kAbs5, kAbs6,
472 kAbs7, kAbs8, kAbs9, kAbsA, kAbsB, kAbsC};
473 std::vector<offset_t> exp_locations = {kAbs1, kAbs2, kAbs3, kAbs4,
474 kAbs5, kAbs6, kAbs9, kAbsC};
475 size_t exp_num_removed = locations.size() - exp_locations.size();
476 size_t num_removed = RemoveUntranslatableAbs32(image, {kBitness, kImageBase},
477 translator, &locations);
478 EXPECT_EQ(exp_num_removed, num_removed);
479 EXPECT_EQ(exp_locations, locations);
480}
481
Samuel Huang06f1ae92018-03-13 18:19:34 +0000482TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) {
Etienne Pierre-doraye53806a2018-10-05 20:15:13 +0000483 // Make |width| a state to reduce repetition.
484 uint32_t width = WidthOf(kBit32);
Samuel Huang06f1ae92018-03-13 18:19:34 +0000485
Etienne Pierre-doraye53806a2018-10-05 20:15:13 +0000486 auto run_test = [&width](const std::vector<offset_t>& expected_locations,
487 std::vector<offset_t>&& locations) {
Samuel Huang06f1ae92018-03-13 18:19:34 +0000488 ASSERT_TRUE(std::is_sorted(locations.begin(), locations.end()));
489 size_t expected_removals = locations.size() - expected_locations.size();
Etienne Pierre-doraye53806a2018-10-05 20:15:13 +0000490 size_t removals = RemoveOverlappingAbs32Locations(width, &locations);
Samuel Huang06f1ae92018-03-13 18:19:34 +0000491 EXPECT_EQ(expected_removals, removals);
492 EXPECT_EQ(expected_locations, locations);
493 };
494
495 // 32-bit tests.
Etienne Pierre-doraye53806a2018-10-05 20:15:13 +0000496 width = WidthOf(kBit32);
Samuel Huang06f1ae92018-03-13 18:19:34 +0000497 run_test(std::vector<offset_t>(), std::vector<offset_t>());
498 run_test({4U}, {4U});
499 run_test({4U, 10U}, {4U, 10U});
500 run_test({4U, 8U}, {4U, 8U});
501 run_test({4U}, {4U, 7U});
502 run_test({4U}, {4U, 4U});
503 run_test({4U, 8U}, {4U, 7U, 8U});
504 run_test({4U, 10U}, {4U, 7U, 10U});
505 run_test({4U, 9U}, {4U, 9U, 10U});
506 run_test({3U}, {3U, 5U, 6U});
507 run_test({3U, 7U}, {3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U});
508 run_test({3U, 7U, 11U}, {3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U});
509 run_test({4U, 8U, 12U}, {4U, 6U, 8U, 10U, 12U});
510 run_test({4U, 8U, 12U, 16U}, {4U, 8U, 12U, 16U});
511 run_test({4U, 8U, 12U}, {4U, 8U, 9U, 12U});
512 run_test({4U}, {4U, 4U, 4U, 4U, 4U, 4U});
513 run_test({3U}, {3U, 4U, 4U, 4U, 5U, 5U});
514 run_test({3U, 7U}, {3U, 4U, 4U, 4U, 7U, 7U, 8U});
515 run_test({10U, 20U, 30U, 40U}, {10U, 20U, 22U, 22U, 30U, 40U});
516 run_test({1000000U, 1000004U}, {1000000U, 1000004U});
517 run_test({1000000U}, {1000000U, 1000002U});
518
519 // 64-bit tests.
Etienne Pierre-doraye53806a2018-10-05 20:15:13 +0000520 width = WidthOf(kBit64);
Samuel Huang06f1ae92018-03-13 18:19:34 +0000521 run_test(std::vector<offset_t>(), std::vector<offset_t>());
522 run_test({4U}, {4U});
523 run_test({4U, 20U}, {4U, 20U});
524 run_test({4U, 12U}, {4U, 12U});
525 run_test({4U}, {4U, 11U});
526 run_test({4U}, {4U, 5U});
527 run_test({4U}, {4U, 4U});
528 run_test({4U, 12U, 20U}, {4U, 12U, 20U});
529 run_test({1U, 9U, 17U}, {1U, 9U, 17U});
530 run_test({1U, 17U}, {1U, 8U, 17U});
531 run_test({1U, 10U}, {1U, 10U, 17U});
532 run_test({3U, 11U}, {3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U});
533 run_test({4U, 12U}, {4U, 6U, 8U, 10U, 12U});
534 run_test({4U, 12U}, {4U, 12U, 16U});
535 run_test({4U, 12U, 20U, 28U}, {4U, 12U, 20U, 28U});
536 run_test({4U}, {4U, 4U, 4U, 4U, 5U, 5U});
537 run_test({3U, 11U}, {3U, 4U, 4U, 4U, 11U, 11U, 12U});
538 run_test({10U, 20U, 30U, 40U}, {10U, 20U, 22U, 22U, 30U, 40U});
539 run_test({1000000U, 1000008U}, {1000000U, 1000008U});
540 run_test({1000000U}, {1000000U, 1000004U});
541}
542
543} // namespace zucchini