packer_unittest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root// Copyright 2014 The Chromium Authors. All rights reserved.
231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root// Use of this source code is governed by a BSD-style license that can be
331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root// found in the LICENSE file.
431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include "packer.h"
631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include <vector>
831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include "elf.h"
931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root#include "testing/gtest/include/gtest/gtest.h"
1031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
1131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootnamespace {
1231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
1331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootvoid AddRelocation(Elf32_Addr addr, std::vector<Elf32_Rel>* relocations) {
1431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  Elf32_Rel relocation = {addr, R_ARM_RELATIVE};
1531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  relocations->push_back(relocation);
1631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root}
1731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
1831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Rootbool CheckRelocation(Elf32_Addr addr, const Elf32_Rel& relocation) {
1931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  return relocation.r_offset == addr && relocation.r_info == R_ARM_RELATIVE;
2031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root}
2131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
223f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root}  // namespace
233f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
243f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootnamespace relocation_packer {
253f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
263f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny RootTEST(Packer, Pack) {
2731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  std::vector<Elf32_Rel> relocations;
283f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  std::vector<uint8_t> packed;
2931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
3031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  RelocationPacker packer;
3131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
3231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Initial relocation.
3331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  AddRelocation(0xd1ce0000, &relocations);
3431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Two more relocations, 4 byte deltas.
3531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  AddRelocation(0xd1ce0004, &relocations);
363f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  AddRelocation(0xd1ce0008, &relocations);
373f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Three more relocations, 8 byte deltas.
383f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  AddRelocation(0xd1ce0010, &relocations);
393f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  AddRelocation(0xd1ce0018, &relocations);
4031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  AddRelocation(0xd1ce0020, &relocations);
4131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
423f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  packed.clear();
433f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  packer.PackRelativeRelocations(relocations, &packed);
443f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
4531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  EXPECT_EQ(16u, packed.size());
463f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Identifier.
473f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ('A', packed[0]);
483f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ('P', packed[1]);
493f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ('R', packed[2]);
503f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ('1', packed[3]);
513f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Count-delta pairs count.
523f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(2u, packed[4]);
533f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // 0xd1ce0000
543f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(128u, packed[5]);
553f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(128u, packed[6]);
563f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(184u, packed[7]);
573f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(142u, packed[8]);
583f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(13u, packed[9]);
593f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Run of two relocations, 4 byte deltas.
603f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(2u, packed[10]);
613f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(4u, packed[11]);
623f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Run of three relocations, 8 byte deltas.
633f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(3u, packed[12]);
643f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(8u, packed[13]);
653f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Padding.
663f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(0u, packed[14]);
673f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_EQ(0u, packed[15]);
683f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root}
693f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
703f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny RootTEST(Packer, Unpack) {
7131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  std::vector<uint8_t> packed;
7231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  std::vector<Elf32_Rel> relocations;
7331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
7431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  RelocationPacker packer;
7531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
7631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Identifier.
7731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back('A');
7831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back('P');
7931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back('R');
8031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back('1');
8131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Count-delta pairs count.
8231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(2u);
833f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // 0xd1ce0000
8431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(128u);
8531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(128u);
8631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(184u);
8731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(142u);
8831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(13u);
8931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Run of two relocations, 4 byte deltas.
9031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(2u);
9131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(4u);
9231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Run of three relocations, 8 byte deltas.
9331cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(3u);
9431cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(8u);
9531cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  // Padding.
9631cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(0u);
9731cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packed.push_back(0u);
9831cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
9931cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  relocations.clear();
10031cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  packer.UnpackRelativeRelocations(packed, &relocations);
10131cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root
10231cf9ecd5035e6b5e8640ec5cc0c3f022e7f6895Kenny Root  EXPECT_EQ(6u, relocations.size());
1033f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Initial relocation.
1043f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_TRUE(CheckRelocation(0xd1ce0000, relocations[0]));
1053f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Two relocations, 4 byte deltas.
1063f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_TRUE(CheckRelocation(0xd1ce0004, relocations[1]));
1073f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_TRUE(CheckRelocation(0xd1ce0008, relocations[2]));
1083f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  // Three relocations, 8 byte deltas.
1093f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_TRUE(CheckRelocation(0xd1ce0010, relocations[3]));
1103f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_TRUE(CheckRelocation(0xd1ce0018, relocations[4]));
1113f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root  EXPECT_TRUE(CheckRelocation(0xd1ce0020, relocations[5]));
1123f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root}
1133f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
1143f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root}  // namespace relocation_packer
1153f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root