Index: third_party/android_platform/bionic/tools/relocation_packer/src/delta_encoder_unittest.cc |
diff --git a/third_party/android_platform/bionic/tools/relocation_packer/src/delta_encoder_unittest.cc b/third_party/android_platform/bionic/tools/relocation_packer/src/delta_encoder_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..06d9c967314f762f3ba762b8985569e8de2043ac |
--- /dev/null |
+++ b/third_party/android_platform/bionic/tools/relocation_packer/src/delta_encoder_unittest.cc |
@@ -0,0 +1,223 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "delta_encoder.h" |
+ |
+#include <vector> |
+#include "elf.h" |
+#include "gtest/gtest.h" |
+ |
+namespace { |
+ |
+template <typename T> |
+void AddRelocation(uint32_t addr, |
+ uint32_t info, |
+ int32_t addend, |
+ std::vector<T>* relocations) { |
+ T relocation; |
+ relocation.r_offset = addr; |
+ relocation.r_info = info; |
+ relocation.r_addend = addend; |
+ relocations->push_back(relocation); |
+} |
+ |
+template <typename T> |
+bool CheckRelocation(uint32_t addr, |
+ uint32_t info, |
+ int32_t addend, |
+ const T& relocation) { |
+ return relocation.r_offset == addr && |
+ relocation.r_info == info && |
+ relocation.r_addend == addend; |
+} |
+ |
+} // namespace |
+ |
+namespace relocation_packer { |
+ |
+template <typename ELF> |
+static void encode() { |
+ std::vector<typename ELF::Rela> relocations; |
+ std::vector<typename ELF::Addr> packed; |
+ |
+ RelocationDeltaCodec<ELF> codec; |
+ |
+ codec.Encode(relocations, &packed); |
+ |
+ ASSERT_EQ(0U, packed.size()); |
+ |
+ // Initial relocation. |
+ AddRelocation(0xf00d0000, 11U, 10000, &relocations); |
+ |
+ codec.Encode(relocations, &packed); |
+ |
+ // size of reloc table, size of group, flags, 3 fields, zero |
+ EXPECT_EQ(7U, packed.size()); |
+ // One pair present. |
+ size_t ndx = 0; |
+ EXPECT_EQ(1U, packed[ndx++]); |
+ EXPECT_EQ(0xf00d0000, packed[ndx++]); |
+ EXPECT_EQ(1U, packed[ndx++]); // group_size |
+ EXPECT_EQ(8U, packed[ndx++]); // flags |
+ // Delta from the neutral element is zero |
+ EXPECT_EQ(0U, packed[ndx++]); // offset_delta |
+ EXPECT_EQ(11U, packed[ndx++]); // info |
+ EXPECT_EQ(10000U, packed[ndx++]); // addend_delta |
+ |
+ // Add a second relocation, 4 byte offset delta, 12 byte addend delta. |
+ // same info |
+ AddRelocation(0xf00d0004, 11U, 10012, &relocations); |
+ |
+ packed.clear(); |
+ codec.Encode(relocations, &packed); |
+ |
+ ndx = 0; |
+ EXPECT_EQ(8U, packed.size()); |
+ |
+ EXPECT_EQ(2U, packed[ndx++]); // relocs count |
+ EXPECT_EQ(0xf00cfffc, packed[ndx++]); // initial offset |
+ EXPECT_EQ(2U, packed[ndx++]); // group count |
+ EXPECT_EQ(11U, packed[ndx++]); // flags |
+ EXPECT_EQ(4U, packed[ndx++]); // group offset delta |
+ EXPECT_EQ(11U, packed[ndx++]); // info |
+ |
+ EXPECT_EQ(10000U, packed[ndx++]); // addend delta |
+ EXPECT_EQ(12U, packed[ndx++]); // addend delta |
+ |
+ // Add a third relocation, 4 byte offset delta, 12 byte addend delta. |
+ // different info |
+ AddRelocation(0xf00d0008, 41U, 10024, &relocations); |
+ |
+ // Add three more relocations, 8 byte offset deltas, -24 byte addend deltas. |
+ AddRelocation(0xf00d0010, 42U, 10000, &relocations); |
+ AddRelocation(0xf00d0018, 42U, 9976, &relocations); |
+ AddRelocation(0xf00d0020, 42U, 9952, &relocations); |
+ |
+ AddRelocation(0xf00d2028, 1042U, 0, &relocations); |
+ AddRelocation(0xf00d2030, 3442U, 0, &relocations); |
+ |
+ packed.clear(); |
+ codec.Encode(relocations, &packed); |
+ |
+ ndx = 0; |
+ EXPECT_EQ(26U, packed.size()); |
+ // Total number of relocs |
+ EXPECT_EQ(8U, packed[ndx++]); |
+ EXPECT_EQ(0xf00cfffc, packed[ndx++]); |
+ // 2 in first group |
+ EXPECT_EQ(2U, packed[ndx++]); |
+ EXPECT_EQ(11U, packed[ndx++]); //flags |
+ EXPECT_EQ(4U, packed[ndx++]); // group offset delta |
+ EXPECT_EQ(11U, packed[ndx++]); // info |
+ |
+ // Initial relocation. |
+ EXPECT_EQ(10000U, packed[ndx++]); // addend delta |
+ // Two relocations, 4 byte offset deltas, 12 byte addend deltas. |
+ EXPECT_EQ(12U, packed[ndx++]); // addend delta |
+ |
+ // second group has only one reloc |
+ EXPECT_EQ(1U, packed[ndx++]); // count |
+ EXPECT_EQ(8U, packed[ndx++]); // flags |
+ |
+ EXPECT_EQ(4U, packed[ndx++]); // offset delta |
+ EXPECT_EQ(41U, packed[ndx++]); // info |
+ EXPECT_EQ(12U, packed[ndx++]); // addend delta |
+ |
+ // next - 3 relocs grouped by info |
+ EXPECT_EQ(3U, packed[ndx++]); // count |
+ EXPECT_EQ(11U, packed[ndx++]); // flags |
+ EXPECT_EQ(8U, packed[ndx++]); // group offset delta |
+ EXPECT_EQ(42U, packed[ndx++]); // info |
+ // Three relocations, 8 byte offset deltas, -24 byte addend deltas. |
+ EXPECT_EQ(static_cast<typename ELF::Addr>(-24), packed[ndx++]); |
+ EXPECT_EQ(static_cast<typename ELF::Addr>(-24), packed[ndx++]); |
+ EXPECT_EQ(static_cast<typename ELF::Addr>(-24), packed[ndx++]); |
+ |
+ // and last - 2 relocations without addend |
+ EXPECT_EQ(2U, packed[ndx++]); |
+ EXPECT_EQ(0U, packed[ndx++]); // flags |
+ // offset_deltas and r_infos for next 2 relocations |
+ EXPECT_EQ(0x2008U, packed[ndx++]); // offset delta |
+ EXPECT_EQ(1042U, packed[ndx++]); // r_info |
+ EXPECT_EQ(0x8U, packed[ndx++]); // offset delta |
+ EXPECT_EQ(3442U, packed[ndx++]); // r_info |
+ |
+ EXPECT_EQ(packed.size(), ndx); |
+} |
+ |
+TEST(Delta, Encode32) { |
+ encode<ELF32_traits>(); |
+} |
+ |
+TEST(Delta, Encode64) { |
+ encode<ELF64_traits>(); |
+} |
+ |
+template <typename ELF> |
+static void decode() { |
+ std::vector<typename ELF::Addr> packed; |
+ std::vector<typename ELF::Rela> relocations; |
+ |
+ RelocationDeltaCodec<ELF> codec; |
+ codec.Decode(packed, &relocations); |
+ |
+ EXPECT_EQ(0U, relocations.size()); |
+ |
+ // Six pairs. |
+ packed.push_back(6U); // count |
+ packed.push_back(0xc0ddfffc); // base offset |
+ packed.push_back(3U); // group count |
+ packed.push_back(11U); // flags |
+ packed.push_back(4U); // offset delta |
+ packed.push_back(11U); // info |
+ // Initial relocation. |
+ packed.push_back(10000U); |
+ // Two relocations, 4 byte offset deltas, 12 byte addend deltas. |
+ packed.push_back(12U); // addend |
+ packed.push_back(12U); // addend |
+ |
+ // Three relocations, 8 byte offset deltas, -24 byte addend deltas. |
+ packed.push_back(1U); // group count |
+ packed.push_back(9U); // flags |
+ packed.push_back(11U); // info |
+ |
+ packed.push_back(8U); |
+ packed.push_back(static_cast<typename ELF::Addr>(-24)); |
+ // next group with 2 relocs |
+ packed.push_back(2U); // group count |
+ packed.push_back(11U); // flags |
+ packed.push_back(8U); // offset |
+ packed.push_back(42U); // info |
+ |
+ packed.push_back(static_cast<typename ELF::Addr>(-24)); // addend |
+ packed.push_back(static_cast<typename ELF::Addr>(-24)); // addend |
+ |
+ relocations.clear(); |
+ codec.Decode(packed, &relocations); |
+ |
+ EXPECT_EQ(6U, relocations.size()); |
+ // Initial relocation. |
+ EXPECT_TRUE(CheckRelocation(0xc0de0000, 11U, 10000, relocations[0])); |
+ // Two relocations, 4 byte offset deltas, 12 byte addend deltas. |
+ EXPECT_TRUE(CheckRelocation(0xc0de0004, 11U, 10012, relocations[1])); |
+ EXPECT_TRUE(CheckRelocation(0xc0de0008, 11U, 10024, relocations[2])); |
+ // Three relocations, 8 byte offset deltas, -24 byte addend deltas. |
+ EXPECT_TRUE(CheckRelocation(0xc0de0010, 11U, 10000, relocations[3])); |
+ EXPECT_TRUE(CheckRelocation(0xc0de0018, 42U, 9976, relocations[4])); |
+ EXPECT_TRUE(CheckRelocation(0xc0de0020, 42U, 9952, relocations[5])); |
+} |
+ |
+TEST(Delta, Decode32) { |
+ decode<ELF32_traits>(); |
+} |
+ |
+TEST(Delta, Decode64) { |
+ decode<ELF64_traits>(); |
+} |
+ |
+// TODO (dimitry): add more tests (fix by 19 January 2038 03:14:07 UTC) |
+// TODO (dimtiry): 1. Incorrect packed array for decode |
+// TODO (dimtiry): 2. Try to catch situation where it is likely to get series of groups with size 1 |
+ |
+} // namespace relocation_packer |