| 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
|
|
|