From 386ae3aff6200dcadce2693996bb2dacfe236428 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 22 Jun 2018 15:52:27 -0700 Subject: Remove relocation_packer. We'll be using the lld built-in relocation packing going forward. Bug: http://b/110715614 Test: builds Change-Id: Ib3c086b642b8e3ab1dac022c0edef3b91665e477 --- tools/relocation_packer/Android.bp | 86 -- tools/relocation_packer/Android.mk | 44 - tools/relocation_packer/LICENSE | 27 - tools/relocation_packer/src/debug.cc | 55 -- tools/relocation_packer/src/debug.h | 118 --- tools/relocation_packer/src/debug_unittest.cc | 122 --- tools/relocation_packer/src/delta_encoder.cc | 307 ------ tools/relocation_packer/src/delta_encoder.h | 132 --- .../src/delta_encoder_unittest.cc | 223 ----- tools/relocation_packer/src/elf_file.cc | 1001 ------------------- tools/relocation_packer/src/elf_file.h | 121 --- tools/relocation_packer/src/elf_file_unittest.cc | 218 ----- tools/relocation_packer/src/elf_traits.h | 68 -- tools/relocation_packer/src/main.cc | 150 --- tools/relocation_packer/src/packer.cc | 67 -- tools/relocation_packer/src/packer.h | 37 - tools/relocation_packer/src/packer_unittest.cc | 300 ------ tools/relocation_packer/src/sleb128.cc | 131 --- tools/relocation_packer/src/sleb128.h | 76 -- tools/relocation_packer/src/sleb128_unittest.cc | 166 ---- .../test_data/elf_file_unittest_relocs.cc | 1014 -------------------- .../test_data/elf_file_unittest_relocs_arm32.so | Bin 92788 -> 0 bytes .../elf_file_unittest_relocs_arm32_packed.so | Bin 88692 -> 0 bytes .../test_data/elf_file_unittest_relocs_arm64.so | Bin 134144 -> 0 bytes .../elf_file_unittest_relocs_arm64_packed.so | Bin 113664 -> 0 bytes .../test_data/elf_file_unittest_relocs_ia32.so | Bin 76736 -> 0 bytes .../elf_file_unittest_relocs_ia32_packed.so | Bin 72640 -> 0 bytes .../test_data/elf_file_unittest_relocs_mips32.so | Bin 134545 -> 0 bytes .../elf_file_unittest_relocs_mips32_packed.so | Bin 130449 -> 0 bytes .../test_data/elf_file_unittest_relocs_x64.so | Bin 108688 -> 0 bytes .../elf_file_unittest_relocs_x64_packed.so | Bin 88208 -> 0 bytes 31 files changed, 4463 deletions(-) delete mode 100644 tools/relocation_packer/Android.bp delete mode 100644 tools/relocation_packer/Android.mk delete mode 100644 tools/relocation_packer/LICENSE delete mode 100644 tools/relocation_packer/src/debug.cc delete mode 100644 tools/relocation_packer/src/debug.h delete mode 100644 tools/relocation_packer/src/debug_unittest.cc delete mode 100644 tools/relocation_packer/src/delta_encoder.cc delete mode 100644 tools/relocation_packer/src/delta_encoder.h delete mode 100644 tools/relocation_packer/src/delta_encoder_unittest.cc delete mode 100644 tools/relocation_packer/src/elf_file.cc delete mode 100644 tools/relocation_packer/src/elf_file.h delete mode 100644 tools/relocation_packer/src/elf_file_unittest.cc delete mode 100644 tools/relocation_packer/src/elf_traits.h delete mode 100644 tools/relocation_packer/src/main.cc delete mode 100644 tools/relocation_packer/src/packer.cc delete mode 100644 tools/relocation_packer/src/packer.h delete mode 100644 tools/relocation_packer/src/packer_unittest.cc delete mode 100644 tools/relocation_packer/src/sleb128.cc delete mode 100644 tools/relocation_packer/src/sleb128.h delete mode 100644 tools/relocation_packer/src/sleb128_unittest.cc delete mode 100644 tools/relocation_packer/test_data/elf_file_unittest_relocs.cc delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so delete mode 100755 tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so (limited to 'tools') diff --git a/tools/relocation_packer/Android.bp b/tools/relocation_packer/Android.bp deleted file mode 100644 index cd6053a43..000000000 --- a/tools/relocation_packer/Android.bp +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (C) 2015 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -cc_defaults { - name: "relocation_packer_flags", - cflags: [ - "-Wall", - "-Werror", - ], - cppflags: [ - "-Wextra", - "-Wunused", - "-Wold-style-cast", - ], - - target: { - darwin: { - enabled: false, - }, - }, -} - -cc_library_host_static { - name: "lib_relocation_packer", - defaults: ["relocation_packer_flags"], - srcs: [ - "src/debug.cc", - "src/delta_encoder.cc", - "src/elf_file.cc", - "src/packer.cc", - "src/sleb128.cc", - ], - - static_libs: [ - "libelf", - "libz", - ], -} - -cc_binary_host { - name: "relocation_packer", - defaults: ["relocation_packer_flags"], - - srcs: ["src/main.cc"], - static_libs: [ - "lib_relocation_packer", - "libelf", - "libz", - "libbase", - ], - - // Statically linking libc++ to make it work from prebuilts - stl: "libc++_static", -} - -cc_test_host { - name: "relocation_packer_unit_tests", - defaults: ["relocation_packer_flags"], - - srcs: [ - "src/debug_unittest.cc", - "src/delta_encoder_unittest.cc", - "src/elf_file_unittest.cc", - "src/sleb128_unittest.cc", - "src/packer_unittest.cc", - ], - - static_libs: [ - "lib_relocation_packer", - "libelf", - "libz", - ], -} diff --git a/tools/relocation_packer/Android.mk b/tools/relocation_packer/Android.mk deleted file mode 100644 index 99056574c..000000000 --- a/tools/relocation_packer/Android.mk +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (C) 2015 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -ifeq ($(HOST_OS),linux) - -# $(1) library name -define copy-test-library -include $(CLEAR_VARS) -LOCAL_IS_HOST_MODULE := true -LOCAL_MODULE := $(1) -LOCAL_MODULE_CLASS := SHARED_LIBRARIES -LOCAL_MODULE_PATH := $(HOST_OUT_EXECUTABLES) -LOCAL_STRIP_MODULE := false -LOCAL_SRC_FILES := test_data/$(1) -include $(BUILD_PREBUILT) -endef - -$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32_packed.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_x64.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_x64_packed.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32.so)) -$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32_packed.so)) - -endif diff --git a/tools/relocation_packer/LICENSE b/tools/relocation_packer/LICENSE deleted file mode 100644 index 972bb2edb..000000000 --- a/tools/relocation_packer/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tools/relocation_packer/src/debug.cc b/tools/relocation_packer/src/debug.cc deleted file mode 100644 index 29d7ab067..000000000 --- a/tools/relocation_packer/src/debug.cc +++ /dev/null @@ -1,55 +0,0 @@ -// 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 "debug.h" - -#include -#include -#include - -namespace relocation_packer { - -// Construct a new message logger. Prints if level is less than or equal to -// the level set with SetVerbose() and predicate is true. -Logger::Logger(Severity severity, int level, bool predicate) { - severity_ = severity; - level_ = level; - predicate_ = predicate; -} - -// On destruction, flush and print the strings accumulated. Abort if FATAL. -Logger::~Logger() { - if (predicate_) { - if (level_ <= max_level_) { - std::ostream* log = severity_ == INFO ? info_stream_ : error_stream_; - std::string tag; - switch (severity_) { - case INFO: tag = "INFO"; break; - case WARNING: tag = "WARNING"; break; - case ERROR: tag = "ERROR"; break; - case FATAL: tag = "FATAL"; break; - } - stream_.flush(); - *log << tag << ": " << stream_.str() << std::endl; - } - if (severity_ == FATAL) - abort(); - } -} - -// Reset to initial state. -void Logger::Reset() { - max_level_ = -1; - info_stream_ = &std::cout; - error_stream_ = &std::cerr; -} - -// Verbosity. Not thread-safe. -int Logger::max_level_ = -1; - -// Logging streams. Not thread-safe. -std::ostream* Logger::info_stream_ = &std::cout; -std::ostream* Logger::error_stream_ = &std::cerr; - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/debug.h b/tools/relocation_packer/src/debug.h deleted file mode 100644 index fdfb79550..000000000 --- a/tools/relocation_packer/src/debug.h +++ /dev/null @@ -1,118 +0,0 @@ -// 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. - -// Logging and checks. Avoids a dependency on base. -// -// LOG(tag) prints messages. Tags are INFO, WARNING, ERROR and FATAL. -// INFO prints to stdout, the others to stderr. FATAL aborts after printing. -// -// LOG_IF(tag, predicate) logs if predicate evaluates to true, else silent. -// -// VLOG(level) logs INFO messages where level is less than or equal to the -// verbosity level set with SetVerbose(). -// -// VLOG_IF(level, predicate) logs INFO if predicate evaluates to true, -// else silent. -// -// CHECK(predicate) logs a FATAL error if predicate is false. -// NOTREACHED() always aborts. -// Log streams can be changed with SetStreams(). Logging is not thread-safe. -// - -#ifndef TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ -#define TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ - -#include -#include -#include - -namespace relocation_packer { - -class Logger { - public: - enum Severity {INFO = 0, WARNING, ERROR, FATAL}; - - // Construct a new message logger. Prints if level is less than or - // equal to the level set with SetVerbose() and predicate is true. - // |severity| is an enumerated severity. - // |level| is the verbosity level. - // |predicate| controls if the logger prints or is silent. - Logger(Severity severity, int level, bool predicate); - - // On destruction, flush and print the strings accumulated in stream_. - ~Logger(); - - // Return the stream for this logger. - std::ostream& GetStream() { return stream_; } - - // Set verbosity level. Messages with a level less than or equal to - // this level are printed, others are discarded. Static, not thread-safe. - static void SetVerbose(int level) { max_level_ = level; } - - // Set info and error logging streams. Static, not thread-safe. - static void SetStreams(std::ostream* info_stream, - std::ostream* error_stream) { - info_stream_ = info_stream; - error_stream_ = error_stream; - } - - // Reset to initial state. - static void Reset(); - - private: - // Message severity, verbosity level, and predicate. - Severity severity_; - int level_; - bool predicate_; - - // String stream, accumulates message text. - std::ostringstream stream_; - - // Verbosity for INFO messages. Not thread-safe. - static int max_level_; - - // Logging streams. Not thread-safe. - static std::ostream* info_stream_; - static std::ostream* error_stream_; -}; - -} // namespace relocation_packer - -// Make logging severities visible globally. -typedef relocation_packer::Logger::Severity LogSeverity; - -// LOG(severity) prints a message with the given severity, and aborts if -// severity is FATAL. LOG_IF(severity, predicate) does the same but only if -// predicate is true. INT_MIN is guaranteed to be less than or equal to -// any verbosity level. -#define LOG(severity) \ - (relocation_packer::Logger(relocation_packer::Logger::severity, INT_MIN, \ - true) \ - .GetStream()) -#define LOG_IF(severity, predicate) \ - (relocation_packer::Logger(relocation_packer::Logger::severity, INT_MIN, \ - (predicate)) \ - .GetStream()) - -// VLOG(level) prints its message as INFO if level is less than or equal to -// the current verbosity level. -#define VLOG(level) \ - (relocation_packer::Logger(relocation_packer::Logger::INFO, (level), true) \ - .GetStream()) -#define VLOG_IF(level, predicate) \ - (relocation_packer::Logger(relocation_packer::Logger::INFO, (level), \ - (predicate)) \ - .GetStream()) - -// CHECK(predicate) fails with a FATAL log message if predicate is false. -#define CHECK(predicate) (LOG_IF(FATAL, !(predicate)) \ - << __FILE__ << ":" << __LINE__ << ": " \ - << __FUNCTION__ << ": CHECK '" #predicate "' failed") - -// NOTREACHED() always fails with a FATAL log message. -#define NOTREACHED(_) (LOG(FATAL) \ - << __FILE__ << ":" << __LINE__ << ": " \ - << __FUNCTION__ << ": NOTREACHED() hit") - -#endif // TOOLS_RELOCATION_PACKER_SRC_DEBUG_H_ diff --git a/tools/relocation_packer/src/debug_unittest.cc b/tools/relocation_packer/src/debug_unittest.cc deleted file mode 100644 index b31e2ae7e..000000000 --- a/tools/relocation_packer/src/debug_unittest.cc +++ /dev/null @@ -1,122 +0,0 @@ -// 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 "debug.h" - -#include -#include "gtest/gtest.h" - -namespace relocation_packer { - -TEST(Debug, Log) { - Logger::Reset(); - std::ostringstream info; - std::ostringstream error; - Logger::SetStreams(&info, &error); - - LOG(INFO) << "INFO log message"; - LOG(WARNING) << "WARNING log message"; - LOG(ERROR) << "ERROR log message"; - - EXPECT_EQ("INFO: INFO log message\n", info.str()); - EXPECT_EQ("WARNING: WARNING log message\n" - "ERROR: ERROR log message\n", error.str()); - Logger::Reset(); -} - -TEST(Debug, LogIf) { - Logger::Reset(); - std::ostringstream info; - std::ostringstream error; - Logger::SetStreams(&info, &error); - - LOG_IF(INFO, true) << "INFO log message"; - LOG_IF(INFO, false) << "INFO log message, SHOULD NOT PRINT"; - LOG_IF(WARNING, true) << "WARNING log message"; - LOG_IF(WARNING, false) << "WARNING log message, SHOULD NOT PRINT"; - LOG_IF(ERROR, true) << "ERROR log message"; - LOG_IF(ERROR, false) << "ERROR log message, SHOULD NOT PRINT"; - LOG_IF(FATAL, false) << "FATAL log message, SHOULD NOT PRINT"; - - EXPECT_EQ("INFO: INFO log message\n", info.str()); - EXPECT_EQ("WARNING: WARNING log message\n" - "ERROR: ERROR log message\n", error.str()); - Logger::Reset(); -} - -TEST(Debug, Vlog) { - Logger::Reset(); - std::ostringstream info; - std::ostringstream error; - Logger::SetStreams(&info, &error); - - VLOG(0) << "VLOG 0 INFO log message, SHOULD NOT PRINT"; - VLOG(1) << "VLOG 1 INFO log message, SHOULD NOT PRINT"; - VLOG(2) << "VLOG 2 INFO log message, SHOULD NOT PRINT"; - - EXPECT_EQ("", info.str()); - EXPECT_EQ("", error.str()); - - Logger::SetVerbose(1); - - VLOG(0) << "VLOG 0 INFO log message"; - VLOG(1) << "VLOG 1 INFO log message"; - VLOG(2) << "VLOG 2 INFO log message, SHOULD NOT PRINT"; - - EXPECT_EQ("INFO: VLOG 0 INFO log message\n" - "INFO: VLOG 1 INFO log message\n", info.str()); - EXPECT_EQ("", error.str()); - Logger::Reset(); -} - -TEST(Debug, VlogIf) { - Logger::Reset(); - std::ostringstream info; - std::ostringstream error; - Logger::SetStreams(&info, &error); - - VLOG_IF(0, true) << "VLOG 0 INFO log message, SHOULD NOT PRINT"; - VLOG_IF(1, true) << "VLOG 1 INFO log message, SHOULD NOT PRINT"; - VLOG_IF(2, true) << "VLOG 2 INFO log message, SHOULD NOT PRINT"; - - EXPECT_EQ("", info.str()); - EXPECT_EQ("", error.str()); - - Logger::SetVerbose(1); - - VLOG_IF(0, true) << "VLOG 0 INFO log message"; - VLOG_IF(0, false) << "VLOG 0 INFO log message, SHOULD NOT PRINT"; - VLOG_IF(1, true) << "VLOG 1 INFO log message"; - VLOG_IF(1, false) << "VLOG 1 INFO log message, SHOULD NOT PRINT"; - VLOG_IF(2, true) << "VLOG 2 INFO log message, SHOULD NOT PRINT"; - VLOG_IF(2, false) << "VLOG 2 INFO log message, SHOULD NOT PRINT"; - - EXPECT_EQ("INFO: VLOG 0 INFO log message\n" - "INFO: VLOG 1 INFO log message\n", info.str()); - EXPECT_EQ("", error.str()); - Logger::Reset(); -} - -TEST(DebugDeathTest, Fatal) { - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - Logger::Reset(); - EXPECT_DEATH(LOG(FATAL) << "FATAL log message", "FATAL: FATAL log message"); - EXPECT_DEATH( - LOG_IF(FATAL, true) << "FATAL log message", "FATAL: FATAL log message"); -} - -TEST(DebugDeathTest, Check) { - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - Logger::Reset(); - CHECK(0 == 0); - EXPECT_DEATH(CHECK(0 == 1), "FATAL: .*:.*: .*: CHECK '0 == 1' failed"); -} - -TEST(DebugDeathTest, NotReached) { - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - Logger::Reset(); - EXPECT_DEATH(NOTREACHED(), "FATAL: .*:.*: .*: NOTREACHED\\(\\) hit"); -} - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/delta_encoder.cc b/tools/relocation_packer/src/delta_encoder.cc deleted file mode 100644 index 8349d7c64..000000000 --- a/tools/relocation_packer/src/delta_encoder.cc +++ /dev/null @@ -1,307 +0,0 @@ -// 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 - -#include "debug.h" - -static constexpr uint32_t RELOCATION_GROUPED_BY_INFO_FLAG = 1; -static constexpr uint32_t RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG = 2; -static constexpr uint32_t RELOCATION_GROUPED_BY_ADDEND_FLAG = 4; -static constexpr uint32_t RELOCATION_GROUP_HAS_ADDEND_FLAG = 8; - -static bool is_relocation_grouped_by_info(uint64_t flags) { - return (flags & RELOCATION_GROUPED_BY_INFO_FLAG) != 0; -} - -static bool is_relocation_grouped_by_offset_delta(uint64_t flags) { - return (flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) != 0; -} - -static bool is_relocation_grouped_by_addend(uint64_t flags) { - return (flags & RELOCATION_GROUPED_BY_ADDEND_FLAG) != 0; -} - -static bool is_relocation_group_has_addend(uint64_t flags) { - return (flags & RELOCATION_GROUP_HAS_ADDEND_FLAG) != 0; -} - -namespace relocation_packer { - -// Encode relocations into a delta encoded (packed) representation. -template -void RelocationDeltaCodec::Encode(const std::vector& relocations, - std::vector* packed) { - if (relocations.size() == 0) - return; - - // Start with the relocation count, then append groups - // TODO(dimitry): we might want to move it to DT_ANDROID_RELCOUNT section - packed->push_back(static_cast(relocations.size())); - - // lets write starting offset (offset of the first reloc - first delta) - ElfAddr start_offset = relocations.size() > 1 ? - relocations[0].r_offset - (relocations[1].r_offset - relocations[0].r_offset) : - relocations[0].r_offset; - - packed->push_back(start_offset); - - // this one is used to calculate delta - ElfAddr previous_addend = 0; - ElfAddr previous_offset = start_offset; - - for (size_t group_start = 0; group_start < relocations.size(); ) { - ElfAddr group_flags = 0; - ElfAddr group_offset_delta = 0; - ElfAddr group_addend = 0; - ElfAddr group_info = 0; - - ElfAddr group_size = 0; - - DetectGroup(relocations, group_start, previous_offset, &group_size, &group_flags, - &group_offset_delta, &group_info, &group_addend); - - // write the group header - packed->push_back(group_size); - packed->push_back(group_flags); - - if (is_relocation_grouped_by_offset_delta(group_flags)) { - packed->push_back(group_offset_delta); - } - - if (is_relocation_grouped_by_info(group_flags)) { - packed->push_back(group_info); - } - - if (is_relocation_group_has_addend(group_flags) && - is_relocation_grouped_by_addend(group_flags)) { - packed->push_back(group_addend - previous_addend); - previous_addend = group_addend; - } - - for (size_t i = 0; i < static_cast(group_size); ++i) { - CHECK((group_start + i) < relocations.size()); - const ElfRela* relocation = &relocations[group_start + i]; - - if (!is_relocation_grouped_by_offset_delta(group_flags)) { - packed->push_back(relocation->r_offset - previous_offset); - } - previous_offset = relocation->r_offset; - - if (!is_relocation_grouped_by_info(group_flags)) { - packed->push_back(relocation->r_info); - } - - if (is_relocation_group_has_addend(group_flags) && - !is_relocation_grouped_by_addend(group_flags)) { - packed->push_back(relocation->r_addend - previous_addend); - previous_addend = relocation->r_addend; - } - } - - // If the relocation group does not have an addend - reset it to 0 - // to simplify addend computation for the group following this one. - if (!is_relocation_group_has_addend(group_flags)) { - previous_addend = 0; - } - - group_start += group_size; - } -} - -// Decode relocations from a delta encoded (packed) representation. -template -void RelocationDeltaCodec::Decode(const std::vector& packed, - std::vector* relocations) { - if (packed.size() < 5) { - return; - } - - size_t ndx = 0; - ElfAddr current_count = 0; - ElfAddr total_count = packed[ndx++]; - - ElfAddr offset = packed[ndx++]; - ElfAddr info = 0; - ElfAddr addend = 0; - - while(current_count < total_count) { - // read group - ElfAddr group_size = packed[ndx++]; - ElfAddr group_flags = packed[ndx++]; - ElfAddr group_offset_delta = 0; - - if (is_relocation_grouped_by_offset_delta(group_flags)) { - group_offset_delta = packed[ndx++]; - } - - if (is_relocation_grouped_by_info(group_flags)) { - info = packed[ndx++]; - } - - if (is_relocation_group_has_addend(group_flags) && - is_relocation_grouped_by_addend(group_flags)) { - addend += packed[ndx++]; - } - - // now read not grouped info - for (ElfAddr i = 0; ipush_back(reloc); - } - - if (!is_relocation_group_has_addend(group_flags)) { - addend = 0; - } - - current_count += group_size; - } -} - -// This function detects a way to group reloc_one and reloc_two, sets up group_flags -// and initializes values for corresponding group_ fields. For example if relocations -// can be grouped by r_info the function will set group_info variable. -template -void RelocationDeltaCodec::DetectGroupFields(const ElfRela& reloc_one, - const ElfRela& reloc_two, - ElfAddr current_offset_delta, - ElfAddr* group_flags, - ElfAddr* group_offset_delta, - ElfAddr* group_info, - ElfAddr* group_addend) { - *group_flags = 0; - - const ElfAddr offset_delta = static_cast(reloc_two.r_offset) - - static_cast(reloc_one.r_offset); - - if (offset_delta == current_offset_delta) { - *group_flags |= RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG; - if (group_offset_delta != nullptr) { - *group_offset_delta = current_offset_delta; - } - } - - if (reloc_one.r_info == reloc_two.r_info) { - *group_flags |= RELOCATION_GROUPED_BY_INFO_FLAG; - if (group_info != nullptr) { - *group_info = reloc_one.r_info; - } - } - - if (reloc_one.r_addend != 0 || reloc_two.r_addend != 0) { - *group_flags |= RELOCATION_GROUP_HAS_ADDEND_FLAG; - if (reloc_one.r_addend == reloc_two.r_addend) { - *group_flags |= RELOCATION_GROUPED_BY_ADDEND_FLAG; - if (group_addend != nullptr) { - *group_addend = reloc_one.r_addend; - } - } - } -} - -// This function is used to detect if there is better group available -// during RelocationDeltaCodec::DetectGroup processing. -// Current implementation prefers having groups without addend (== zero addend) -// to any other groups field with the ratio 3:1. This is because addend tends -// to be more unevenly distributed than other fields. -static uint32_t group_weight(uint64_t flags) { - uint32_t weight = 0; - if (!is_relocation_group_has_addend(flags)) { - weight += 3; - } else if (is_relocation_grouped_by_addend(flags)) { - weight += 1; - } - - if (is_relocation_grouped_by_offset_delta(flags)) { - weight += 1; - } - - if (is_relocation_grouped_by_info(flags)) { - weight += 1; - } - - return weight; -} - -template -void RelocationDeltaCodec::DetectGroup(const std::vector& relocations, - size_t group_starts_with, ElfAddr previous_offset, - ElfAddr* group_size, ElfAddr* group_flags, - ElfAddr* group_offset_delta, ElfAddr* group_info, - ElfAddr* group_addend) { - CHECK(group_starts_with < relocations.size()); - CHECK(group_flags != nullptr); - - const ElfRela& reloc_one = relocations[group_starts_with++]; - if (group_starts_with == relocations.size()) { - *group_flags = reloc_one.r_addend == 0 ? 0 : RELOCATION_GROUP_HAS_ADDEND_FLAG; - *group_size = 1; - return; - } - - const ElfAddr offset_delta = reloc_one.r_offset - previous_offset; - - // detect group_flags - DetectGroupFields(reloc_one, relocations[group_starts_with], offset_delta, group_flags, - group_offset_delta, group_info, group_addend); - - if (group_starts_with + 1 == relocations.size()) { - *group_size = 2; - return; - } - - ElfAddr cnt = 1; - for (size_t i = group_starts_with; i < relocations.size() - 1; ++i) { - ElfAddr candidate_flags; - // check if next group (reloc_current; reloc_next) has better grouped_by flags - DetectGroupFields(relocations[i], relocations[i+1], offset_delta, &candidate_flags, - nullptr, nullptr, nullptr); - - if (group_weight(*group_flags) < group_weight(candidate_flags)) { - break; - } - cnt++; - - if (candidate_flags != *group_flags) { - break; - } - - if (i + 1 == relocations.size() - 1) { // last one - cnt++; - } - } - - // if as a result of checking candidates we ended up with cnt == 1 - // reset flags to the default state - if (cnt == 1) { - *group_flags = reloc_one.r_addend == 0 ? 0 : RELOCATION_GROUP_HAS_ADDEND_FLAG; - } - - *group_size = cnt; -} - -template class RelocationDeltaCodec; -template class RelocationDeltaCodec; - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/delta_encoder.h b/tools/relocation_packer/src/delta_encoder.h deleted file mode 100644 index 46c324c49..000000000 --- a/tools/relocation_packer/src/delta_encoder.h +++ /dev/null @@ -1,132 +0,0 @@ -// 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. - -// Delta encode and decode REL/RELA section of elf file. -// -// The encoded data format is sequence of elements of ElfAddr type (unsigned long): -// -// [00] relocation_count - the total count of relocations -// [01] initial r_offset - this is initial r_offset for the -// relocation table. -// followed by group structures: -// [02] group -// ... -// [nn] group - -// the generalized format of the group is (! - always present ? - depends on group_flags): -// -------------- -// ! group_size -// ! group_flags -// ? group_r_offset_delta when RELOCATION_GROUPED_BY_OFFSET_DELTA flag is set -// ? group_r_info when RELOCATION_GROUPED_BY_INFO flag is set -// ? group_r_addend_group_delta when RELOCATION_GROUP_HAS_ADDEND and RELOCATION_GROUPED_BY_ADDEND -// flag is set -// -// The group description is followed by individual relocations. -// please note that there is a case when individual relocation -// section could be empty - that is if every field ends up grouped. -// -// The format for individual relocations section is: -// ? r_offset_delta - when RELOCATION_GROUPED_BY_OFFSET_DELTA is not set -// ? r_info - when RELOCATION_GROUPED_BY_INFO flag is not set -// ? r_addend_delta - RELOCATION_GROUP_HAS_ADDEND is set and RELOCATION_GROUPED_BY_ADDEND is not set -// -// For example lets pack the following relocations: -// -// Relocation section '.rela.dyn' at offset 0xbf58 contains 939 entries: -// Offset Info Type Symbol's Value Symbol's Name + Addend -// 00000000000a2178 0000000000000403 R_AARCH64_RELATIVE 177a8 -// 00000000000a2180 0000000000000403 R_AARCH64_RELATIVE 177cc -// 00000000000a2188 0000000000000403 R_AARCH64_RELATIVE 177e0 -// 00000000000a2190 0000000000000403 R_AARCH64_RELATIVE 177f4 -// 00000000000a2198 0000000000000403 R_AARCH64_RELATIVE 17804 -// 00000000000a21a0 0000000000000403 R_AARCH64_RELATIVE 17818 -// 00000000000a21a8 0000000000000403 R_AARCH64_RELATIVE 1782c -// 00000000000a21b0 0000000000000403 R_AARCH64_RELATIVE 17840 -// 00000000000a21b8 0000000000000403 R_AARCH64_RELATIVE 17854 -// 00000000000a21c0 0000000000000403 R_AARCH64_RELATIVE 17868 -// 00000000000a21c8 0000000000000403 R_AARCH64_RELATIVE 1787c -// 00000000000a21d0 0000000000000403 R_AARCH64_RELATIVE 17890 -// 00000000000a21d8 0000000000000403 R_AARCH64_RELATIVE 178a4 -// 00000000000a21e8 0000000000000403 R_AARCH64_RELATIVE 178b8 -// -// The header is going to be -// [00] 14 <- count -// [01] 0x00000000000a2170 <- initial relocation (first relocation - delta, -// the delta is 8 in this case) -// -- starting the first and only group -// [03] 14 <- group size -// [03] 0xb <- flags RELOCATION_GROUP_HAS_ADDEND | RELOCATION_GROUPED_BY_OFFSET_DELTA -// | RELOCATION_GROUPED_BY_INFO -// [04] 8 <- offset delta -// [05] 0x403 <- r_info -// -- end of group definition, starting list of r_addend deltas -// [06] 0x177a8 -// [07] 0x24 = 177cc - 177a8 -// [08] 0x14 = 177e0 - 177cc -// [09] 0x14 = 177f4 - 177e0 -// [10] 0x10 = 17804 - 177f4 -// [11] 0x14 = 17818 - 17804 -// [12] 0x14 = 1782c - 17818 -// [13] 0x14 = 17840 - 1782c -// [14] 0x14 = 17854 - 17840 -// [15] 0x14 = 17868 - 17854 -// [16] 0x14 = 1787c - 17868 -// [17] 0x14 = 17890 - 1787c -// [18] 0x14 = 178a4 - 17890 -// [19] 0x14 = 178b8 - 178a4 -// -- the end. - -// TODO (dimitry): consider using r_addend_group_delta in the way we use group offset delta, it can -// save us more bytes... - -// The input ends when sum(group_size) == relocation_count - -#ifndef TOOLS_RELOCATION_PACKER_SRC_DELTA_ENCODER_H_ -#define TOOLS_RELOCATION_PACKER_SRC_DELTA_ENCODER_H_ - -#include - -#include "elf.h" -#include "elf_traits.h" - -namespace relocation_packer { - -// A RelocationDeltaCodec packs vectors of relative relocations with -// addends into more compact forms, and unpacks them to reproduce the -// pre-packed data. -template -class RelocationDeltaCodec { - public: - typedef typename ELF::Addr ElfAddr; - typedef typename ELF::Rela ElfRela; - - // Encode relocations with addends into a more compact form. - // |relocations| is a vector of relative relocation with addend structs. - // |packed| is the vector of packed words into which relocations are packed. - static void Encode(const std::vector& relocations, - std::vector* packed); - - // Decode relative relocations with addends from their more compact form. - // |packed| is the vector of packed relocations. - // |relocations| is a vector of unpacked relative relocations. - static void Decode(const std::vector& packed, - std::vector* relocations); - - private: - static void DetectGroup(const std::vector& relocations, - size_t group_starts_with, ElfAddr previous_offset, - ElfAddr* group_size, ElfAddr* group_flags, - ElfAddr* group_offset_delta, ElfAddr* group_info, - ElfAddr* group_addend); - - static void DetectGroupFields(const ElfRela& reloc_one, const ElfRela& reloc_two, - ElfAddr current_offset_delta, ElfAddr* group_flags, - ElfAddr* group_offset_delta, ElfAddr* group_info, - ElfAddr* group_addend); -}; - -} // namespace relocation_packer - -#endif // TOOLS_RELOCATION_PACKER_SRC_DELTA_ENCODER_H_ diff --git a/tools/relocation_packer/src/delta_encoder_unittest.cc b/tools/relocation_packer/src/delta_encoder_unittest.cc deleted file mode 100644 index 06d9c9673..000000000 --- a/tools/relocation_packer/src/delta_encoder_unittest.cc +++ /dev/null @@ -1,223 +0,0 @@ -// 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 -#include "elf.h" -#include "gtest/gtest.h" - -namespace { - -template -void AddRelocation(uint32_t addr, - uint32_t info, - int32_t addend, - std::vector* relocations) { - T relocation; - relocation.r_offset = addr; - relocation.r_info = info; - relocation.r_addend = addend; - relocations->push_back(relocation); -} - -template -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 -static void encode() { - std::vector relocations; - std::vector packed; - - RelocationDeltaCodec 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(-24), packed[ndx++]); - EXPECT_EQ(static_cast(-24), packed[ndx++]); - EXPECT_EQ(static_cast(-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(); -} - -TEST(Delta, Encode64) { - encode(); -} - -template -static void decode() { - std::vector packed; - std::vector relocations; - - RelocationDeltaCodec 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(-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(-24)); // addend - packed.push_back(static_cast(-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(); -} - -TEST(Delta, Decode64) { - decode(); -} - -// 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 diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc deleted file mode 100644 index 275e4865b..000000000 --- a/tools/relocation_packer/src/elf_file.cc +++ /dev/null @@ -1,1001 +0,0 @@ -// 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. - -// Implementation notes: -// -// We need to remove a piece from the ELF shared library. However, we also -// want to avoid fixing DWARF cfi data and relative relocation addresses. -// So after packing we shift offets and starting address of the RX segment -// while preserving code/data vaddrs location. -// This requires some fixups for symtab/hash/gnu_hash dynamic section addresses. - -#include "elf_file.h" - -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "elf_traits.h" -#include "libelf.h" -#include "packer.h" - -namespace relocation_packer { - -// Out-of-band dynamic tags used to indicate the offset and size of the -// android packed relocations section. -static constexpr int32_t DT_ANDROID_REL = DT_LOOS + 2; -static constexpr int32_t DT_ANDROID_RELSZ = DT_LOOS + 3; - -static constexpr int32_t DT_ANDROID_RELA = DT_LOOS + 4; -static constexpr int32_t DT_ANDROID_RELASZ = DT_LOOS + 5; - -static constexpr uint32_t SHT_ANDROID_REL = SHT_LOOS + 1; -static constexpr uint32_t SHT_ANDROID_RELA = SHT_LOOS + 2; - -static const size_t kPageSize = 4096; - -// Alignment to preserve, in bytes. This must be at least as large as the -// largest d_align and sh_addralign values found in the loaded file. -// Out of caution for RELRO page alignment, we preserve to a complete target -// page. See http://www.airs.com/blog/archives/189. -static const size_t kPreserveAlignment = kPageSize; - -// Get section data. Checks that the section has exactly one data entry, -// so that the section size and the data size are the same. True in -// practice for all sections we resize when packing or unpacking. Done -// by ensuring that a call to elf_getdata(section, data) returns NULL as -// the next data entry. -static Elf_Data* GetSectionData(Elf_Scn* section) { - Elf_Data* data = elf_getdata(section, NULL); - CHECK(data && elf_getdata(section, data) == NULL); - return data; -} - -// Rewrite section data. Allocates new data and makes it the data element's -// buffer. Relies on program exit to free allocated data. -static void RewriteSectionData(Elf_Scn* section, - const void* section_data, - size_t size) { - Elf_Data* data = GetSectionData(section); - CHECK(size == data->d_size); - uint8_t* area = new uint8_t[size]; - memcpy(area, section_data, size); - data->d_buf = area; -} - -// Verbose ELF header logging. -template -static void VerboseLogElfHeader(const Ehdr* elf_header) { - VLOG(1) << "e_phoff = " << elf_header->e_phoff; - VLOG(1) << "e_shoff = " << elf_header->e_shoff; - VLOG(1) << "e_ehsize = " << elf_header->e_ehsize; - VLOG(1) << "e_phentsize = " << elf_header->e_phentsize; - VLOG(1) << "e_phnum = " << elf_header->e_phnum; - VLOG(1) << "e_shnum = " << elf_header->e_shnum; - VLOG(1) << "e_shstrndx = " << elf_header->e_shstrndx; -} - -// Verbose ELF program header logging. -template -static void VerboseLogProgramHeader(size_t program_header_index, - const Phdr* program_header) { - std::string type; - switch (program_header->p_type) { - case PT_NULL: type = "NULL"; break; - case PT_LOAD: type = "LOAD"; break; - case PT_DYNAMIC: type = "DYNAMIC"; break; - case PT_INTERP: type = "INTERP"; break; - case PT_PHDR: type = "PHDR"; break; - case PT_GNU_RELRO: type = "GNU_RELRO"; break; - case PT_GNU_STACK: type = "GNU_STACK"; break; - case PT_ARM_EXIDX: type = "EXIDX"; break; - default: type = "(OTHER)"; break; - } - VLOG(1) << "phdr[" << program_header_index << "] : " << type; - VLOG(1) << " p_offset = " << program_header->p_offset; - VLOG(1) << " p_vaddr = " << program_header->p_vaddr; - VLOG(1) << " p_paddr = " << program_header->p_paddr; - VLOG(1) << " p_filesz = " << program_header->p_filesz; - VLOG(1) << " p_memsz = " << program_header->p_memsz; - VLOG(1) << " p_flags = " << program_header->p_flags; - VLOG(1) << " p_align = " << program_header->p_align; -} - -// Verbose ELF section header logging. -template -static void VerboseLogSectionHeader(const std::string& section_name, - const Shdr* section_header) { - VLOG(1) << "section " << section_name; - VLOG(1) << " sh_addr = " << section_header->sh_addr; - VLOG(1) << " sh_offset = " << section_header->sh_offset; - VLOG(1) << " sh_size = " << section_header->sh_size; - VLOG(1) << " sh_entsize = " << section_header->sh_entsize; - VLOG(1) << " sh_addralign = " << section_header->sh_addralign; -} - -// Verbose ELF section data logging. -static void VerboseLogSectionData(const Elf_Data* data) { - VLOG(1) << " data"; - VLOG(1) << " d_buf = " << data->d_buf; - VLOG(1) << " d_off = " << data->d_off; - VLOG(1) << " d_size = " << data->d_size; - VLOG(1) << " d_align = " << data->d_align; -} - -// Load the complete ELF file into a memory image in libelf, and identify -// the .rel.dyn or .rela.dyn, .dynamic, and .android.rel.dyn or -// .android.rela.dyn sections. No-op if the ELF file has already been loaded. -template -bool ElfFile::Load() { - if (elf_) - return true; - - Elf* elf = elf_begin(fd_, ELF_C_RDWR, NULL); - CHECK(elf); - - if (elf_kind(elf) != ELF_K_ELF) { - LOG(ERROR) << "File not in ELF format"; - return false; - } - - auto elf_header = ELF::getehdr(elf); - if (!elf_header) { - LOG(ERROR) << "Failed to load ELF header: " << elf_errmsg(elf_errno()); - return false; - } - - if (elf_header->e_type != ET_DYN) { - LOG(ERROR) << "ELF file is not a shared object"; - return false; - } - - // Require that our endianness matches that of the target, and that both - // are little-endian. Safe for all current build/target combinations. - const int endian = elf_header->e_ident[EI_DATA]; - CHECK(endian == ELFDATA2LSB); - CHECK(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__); - - const int file_class = elf_header->e_ident[EI_CLASS]; - VLOG(1) << "endian = " << endian << ", file class = " << file_class; - VerboseLogElfHeader(elf_header); - - auto elf_program_header = ELF::getphdr(elf); - CHECK(elf_program_header != nullptr); - - const typename ELF::Phdr* dynamic_program_header = NULL; - for (size_t i = 0; i < elf_header->e_phnum; ++i) { - auto program_header = &elf_program_header[i]; - VerboseLogProgramHeader(i, program_header); - - if (program_header->p_type == PT_DYNAMIC) { - CHECK(dynamic_program_header == NULL); - dynamic_program_header = program_header; - } - } - CHECK(dynamic_program_header != nullptr); - - size_t string_index; - elf_getshdrstrndx(elf, &string_index); - - // Notes of the dynamic relocations, packed relocations, and .dynamic - // sections. Found while iterating sections, and later stored in class - // attributes. - Elf_Scn* found_relocations_section = nullptr; - Elf_Scn* found_dynamic_section = nullptr; - - // Notes of relocation section types seen. We require one or the other of - // these; both is unsupported. - bool has_rel_relocations = false; - bool has_rela_relocations = false; - bool has_android_relocations = false; - - Elf_Scn* section = NULL; - while ((section = elf_nextscn(elf, section)) != nullptr) { - auto section_header = ELF::getshdr(section); - std::string name = elf_strptr(elf, string_index, section_header->sh_name); - VerboseLogSectionHeader(name, section_header); - - // Note relocation section types. - if (section_header->sh_type == SHT_REL || section_header->sh_type == SHT_ANDROID_REL) { - has_rel_relocations = true; - } - if (section_header->sh_type == SHT_RELA || section_header->sh_type == SHT_ANDROID_RELA) { - has_rela_relocations = true; - } - - // Note special sections as we encounter them. - if ((name == ".rel.dyn" || name == ".rela.dyn") && - section_header->sh_size > 0) { - found_relocations_section = section; - - // Note if relocation section is already packed - has_android_relocations = - section_header->sh_type == SHT_ANDROID_REL || - section_header->sh_type == SHT_ANDROID_RELA; - } - - if (section_header->sh_offset == dynamic_program_header->p_offset) { - found_dynamic_section = section; - } - - // Ensure we preserve alignment, repeated later for the data block(s). - CHECK(section_header->sh_addralign <= kPreserveAlignment); - - Elf_Data* data = NULL; - while ((data = elf_getdata(section, data)) != NULL) { - CHECK(data->d_align <= kPreserveAlignment); - VerboseLogSectionData(data); - } - } - - // Loading failed if we did not find the required special sections. - if (!found_dynamic_section) { - LOG(ERROR) << "Missing .dynamic section"; - return false; - } - - if (found_relocations_section != nullptr) { - // Loading failed if we could not identify the relocations type. - if (!has_rel_relocations && !has_rela_relocations) { - LOG(ERROR) << "No relocations sections found"; - return false; - } - if (has_rel_relocations && has_rela_relocations) { - LOG(ERROR) << "Multiple relocations sections with different types found, " - << "not currently supported"; - return false; - } - } - - elf_ = elf; - relocations_section_ = found_relocations_section; - dynamic_section_ = found_dynamic_section; - relocations_type_ = has_rel_relocations ? REL : RELA; - has_android_relocations_ = has_android_relocations; - return true; -} - -// Helper for ResizeSection(). Adjust the main ELF header for the hole. -template -static void AdjustElfHeaderForHole(typename ELF::Ehdr* elf_header, - typename ELF::Off hole_start, - ssize_t hole_size) { - if (elf_header->e_phoff > hole_start) { - elf_header->e_phoff += hole_size; - VLOG(1) << "e_phoff adjusted to " << elf_header->e_phoff; - } - if (elf_header->e_shoff > hole_start) { - elf_header->e_shoff += hole_size; - VLOG(1) << "e_shoff adjusted to " << elf_header->e_shoff; - } -} - -// Helper for ResizeSection(). Adjust all section headers for the hole. -template -static void AdjustSectionHeadersForHole(Elf* elf, - typename ELF::Off hole_start, - ssize_t hole_size) { - size_t string_index; - elf_getshdrstrndx(elf, &string_index); - - Elf_Scn* section = NULL; - while ((section = elf_nextscn(elf, section)) != NULL) { - auto section_header = ELF::getshdr(section); - std::string name = elf_strptr(elf, string_index, section_header->sh_name); - - if (section_header->sh_offset > hole_start) { - section_header->sh_offset += hole_size; - VLOG(1) << "section " << name - << " sh_offset adjusted to " << section_header->sh_offset; - } else { - section_header->sh_addr -= hole_size; - VLOG(1) << "section " << name - << " sh_addr adjusted to " << section_header->sh_addr; - } - } -} - -// Helpers for ResizeSection(). On packing, reduce p_align for LOAD segments -// to 4kb if larger. On unpacking, restore p_align for LOAD segments if -// packing reduced it to 4kb. Return true if p_align was changed. -template -static bool ClampLoadSegmentAlignment(typename ELF::Phdr* program_header) { - CHECK(program_header->p_type == PT_LOAD); - - // If large, reduce p_align for a LOAD segment to page size on packing. - if (program_header->p_align > kPageSize) { - program_header->p_align = kPageSize; - return true; - } - return false; -} - -template -static bool RestoreLoadSegmentAlignment(typename ELF::Phdr* program_headers, - size_t count, - typename ELF::Phdr* program_header) { - CHECK(program_header->p_type == PT_LOAD); - - // If p_align was reduced on packing, restore it to its previous value - // on unpacking. We do this by searching for a different LOAD segment - // and setting p_align to that of the other LOAD segment found. - // - // Relies on the following observations: - // - a packable ELF executable has more than one LOAD segment; - // - before packing all LOAD segments have the same p_align; - // - on packing we reduce only one LOAD segment's p_align. - if (program_header->p_align == kPageSize) { - for (size_t i = 0; i < count; ++i) { - typename ELF::Phdr* other_header = &program_headers[i]; - if (other_header->p_type == PT_LOAD && other_header != program_header) { - program_header->p_align = other_header->p_align; - return true; - } - } - LOG(WARNING) << "Cannot find a LOAD segment from which to restore p_align"; - } - return false; -} - -template -static bool AdjustLoadSegmentAlignment(typename ELF::Phdr* program_headers, - size_t count, - typename ELF::Phdr* program_header, - ssize_t hole_size) { - CHECK(program_header->p_type == PT_LOAD); - - bool status = false; - if (hole_size < 0) { - status = ClampLoadSegmentAlignment(program_header); - } else if (hole_size > 0) { - status = RestoreLoadSegmentAlignment(program_headers, - count, - program_header); - } - return status; -} - -// Helper for ResizeSection(). Adjust the offsets of any program headers -// that have offsets currently beyond the hole start, and adjust the -// virtual and physical addrs (and perhaps alignment) of the others. -template -static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers, - size_t count, - typename ELF::Off hole_start, - ssize_t hole_size) { - int alignment_changes = 0; - for (size_t i = 0; i < count; ++i) { - typename ELF::Phdr* program_header = &program_headers[i]; - - // Do not adjust PT_GNU_STACK - it confuses gdb and results - // in incorrect unwinding if the executable is stripped after - // packing. - if (program_header->p_type == PT_GNU_STACK) { - continue; - } - - if (program_header->p_offset > hole_start) { - // The hole start is past this segment, so adjust offset. - program_header->p_offset += hole_size; - VLOG(1) << "phdr[" << i - << "] p_offset adjusted to "<< program_header->p_offset; - } else { - program_header->p_vaddr -= hole_size; - program_header->p_paddr -= hole_size; - - // If packing, clamp LOAD segment alignment to 4kb to prevent strip - // from adjusting it unnecessarily if run on a packed file. If - // unpacking, attempt to restore a reduced alignment to its previous - // value. Ensure that we do this on at most one LOAD segment. - if (program_header->p_type == PT_LOAD) { - alignment_changes += AdjustLoadSegmentAlignment(program_headers, - count, - program_header, - hole_size); - LOG_IF(FATAL, alignment_changes > 1) - << "Changed p_align on more than one LOAD segment"; - } - - VLOG(1) << "phdr[" << i - << "] p_vaddr adjusted to "<< program_header->p_vaddr - << "; p_paddr adjusted to "<< program_header->p_paddr - << "; p_align adjusted to "<< program_header->p_align; - } - } -} - -// Helper for ResizeSection(). Find the first loadable segment in the -// file. We expect it to map from file offset zero. -template -static typename ELF::Phdr* FindLoadSegmentForHole(typename ELF::Phdr* program_headers, - size_t count, - typename ELF::Off hole_start) { - for (size_t i = 0; i < count; ++i) { - typename ELF::Phdr* program_header = &program_headers[i]; - - if (program_header->p_type == PT_LOAD && - program_header->p_offset <= hole_start && - (program_header->p_offset + program_header->p_filesz) >= hole_start ) { - return program_header; - } - } - LOG(FATAL) << "Cannot locate a LOAD segment with hole_start=0x" << std::hex << hole_start; - NOTREACHED(); - - return nullptr; -} - -// Helper for ResizeSection(). Rewrite program headers. -template -static void RewriteProgramHeadersForHole(Elf* elf, - typename ELF::Off hole_start, - ssize_t hole_size) { - const typename ELF::Ehdr* elf_header = ELF::getehdr(elf); - CHECK(elf_header); - - typename ELF::Phdr* elf_program_header = ELF::getphdr(elf); - CHECK(elf_program_header); - - const size_t program_header_count = elf_header->e_phnum; - - // Locate the segment that we can overwrite to form the new LOAD entry, - // and the segment that we are going to split into two parts. - typename ELF::Phdr* target_load_header = - FindLoadSegmentForHole(elf_program_header, program_header_count, hole_start); - - VLOG(1) << "phdr[" << target_load_header - elf_program_header << "] adjust"; - // Adjust PT_LOAD program header memsz and filesz - target_load_header->p_filesz += hole_size; - target_load_header->p_memsz += hole_size; - - // Adjust the offsets and p_vaddrs - AdjustProgramHeaderFields(elf_program_header, - program_header_count, - hole_start, - hole_size); -} - -// Helper for ResizeSection(). Locate and return the dynamic section. -template -static Elf_Scn* GetDynamicSection(Elf* elf) { - const typename ELF::Ehdr* elf_header = ELF::getehdr(elf); - CHECK(elf_header); - - const typename ELF::Phdr* elf_program_header = ELF::getphdr(elf); - CHECK(elf_program_header); - - // Find the program header that describes the dynamic section. - const typename ELF::Phdr* dynamic_program_header = NULL; - for (size_t i = 0; i < elf_header->e_phnum; ++i) { - const typename ELF::Phdr* program_header = &elf_program_header[i]; - - if (program_header->p_type == PT_DYNAMIC) { - dynamic_program_header = program_header; - } - } - CHECK(dynamic_program_header); - - // Now find the section with the same offset as this program header. - Elf_Scn* dynamic_section = NULL; - Elf_Scn* section = NULL; - while ((section = elf_nextscn(elf, section)) != NULL) { - typename ELF::Shdr* section_header = ELF::getshdr(section); - - if (section_header->sh_offset == dynamic_program_header->p_offset) { - dynamic_section = section; - } - } - CHECK(dynamic_section != NULL); - - return dynamic_section; -} - -// Helper for ResizeSection(). Adjust the .dynamic section for the hole. -template -void ElfFile::AdjustDynamicSectionForHole(Elf_Scn* dynamic_section, - typename ELF::Off hole_start, - ssize_t hole_size, - relocations_type_t relocations_type) { - CHECK(relocations_type != NONE); - Elf_Data* data = GetSectionData(dynamic_section); - - auto dynamic_base = reinterpret_cast(data->d_buf); - std::vector dynamics( - dynamic_base, - dynamic_base + data->d_size / sizeof(dynamics[0])); - - if (hole_size > 0) { // expanding - hole_start += hole_size; - } - - for (size_t i = 0; i < dynamics.size(); ++i) { - typename ELF::Dyn* dynamic = &dynamics[i]; - const typename ELF::Sword tag = dynamic->d_tag; - - // Any tags that hold offsets are adjustment candidates. - const bool is_adjustable = (tag == DT_PLTGOT || - tag == DT_HASH || - tag == DT_GNU_HASH || - tag == DT_STRTAB || - tag == DT_SYMTAB || - tag == DT_RELA || - tag == DT_INIT || - tag == DT_FINI || - tag == DT_REL || - tag == DT_JMPREL || - tag == DT_INIT_ARRAY || - tag == DT_FINI_ARRAY || - tag == DT_VERSYM || - tag == DT_VERNEED || - tag == DT_VERDEF || - tag == DT_ANDROID_REL|| - tag == DT_ANDROID_RELA); - - if (is_adjustable && dynamic->d_un.d_ptr <= hole_start) { - dynamic->d_un.d_ptr -= hole_size; - VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag - << " d_ptr adjusted to " << dynamic->d_un.d_ptr; - } - - // DT_RELSZ or DT_RELASZ indicate the overall size of relocations. - // Only one will be present. Adjust by hole size. - if (tag == DT_RELSZ || tag == DT_RELASZ || tag == DT_ANDROID_RELSZ || tag == DT_ANDROID_RELASZ) { - dynamic->d_un.d_val += hole_size; - VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag - << " d_val adjusted to " << dynamic->d_un.d_val; - } - - // Special case: DT_MIPS_RLD_MAP_REL stores the difference between dynamic - // entry address and the address of the _r_debug (used by GDB) - // since the dynamic section and target address are on the - // different sides of the hole it needs to be adjusted accordingly - if (tag == DT_MIPS_RLD_MAP_REL) { - dynamic->d_un.d_val += hole_size; - VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag - << " d_val adjusted to " << dynamic->d_un.d_val; - } - - // Ignore DT_RELCOUNT and DT_RELACOUNT: (1) nobody uses them and - // technically (2) the relative relocation count is not changed. - - // DT_RELENT and DT_RELAENT don't change, ignore them as well. - } - - void* section_data = &dynamics[0]; - size_t bytes = dynamics.size() * sizeof(dynamics[0]); - RewriteSectionData(dynamic_section, section_data, bytes); -} - -// Resize a section. If the new size is larger than the current size, open -// up a hole by increasing file offsets that come after the hole. If smaller -// than the current size, remove the hole by decreasing those offsets. -template -void ElfFile::ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size, - typename ELF::Word new_sh_type, - relocations_type_t relocations_type) { - - size_t string_index; - elf_getshdrstrndx(elf, &string_index); - auto section_header = ELF::getshdr(section); - std::string name = elf_strptr(elf, string_index, section_header->sh_name); - - if (section_header->sh_size == new_size) { - return; - } - - // Require that the section size and the data size are the same. True - // in practice for all sections we resize when packing or unpacking. - Elf_Data* data = GetSectionData(section); - CHECK(data->d_off == 0 && data->d_size == section_header->sh_size); - - // Require that the section is not zero-length (that is, has allocated - // data that we can validly expand). - CHECK(data->d_size && data->d_buf); - - const auto hole_start = section_header->sh_offset; - const ssize_t hole_size = new_size - data->d_size; - - VLOG_IF(1, (hole_size > 0)) << "expand section (" << name << ") size: " << - data->d_size << " -> " << (data->d_size + hole_size); - VLOG_IF(1, (hole_size < 0)) << "shrink section (" << name << ") size: " << - data->d_size << " -> " << (data->d_size + hole_size); - - // libelf overrides sh_entsize for known sh_types, so it does not matter what we set - // for SHT_REL/SHT_RELA. - typename ELF::Xword new_entsize = - (new_sh_type == SHT_ANDROID_REL || new_sh_type == SHT_ANDROID_RELA) ? 1 : 0; - - VLOG(1) << "Update section (" << name << ") entry size: " << - section_header->sh_entsize << " -> " << new_entsize; - - // Resize the data and the section header. - data->d_size += hole_size; - section_header->sh_size += hole_size; - section_header->sh_entsize = new_entsize; - section_header->sh_type = new_sh_type; - - // Add the hole size to all offsets in the ELF file that are after the - // start of the hole. If the hole size is positive we are expanding the - // section to create a new hole; if negative, we are closing up a hole. - - // Start with the main ELF header. - typename ELF::Ehdr* elf_header = ELF::getehdr(elf); - AdjustElfHeaderForHole(elf_header, hole_start, hole_size); - - // Adjust all section headers. - AdjustSectionHeadersForHole(elf, hole_start, hole_size); - - // Rewrite the program headers to either split or coalesce segments, - // and adjust dynamic entries to match. - RewriteProgramHeadersForHole(elf, hole_start, hole_size); - - Elf_Scn* dynamic_section = GetDynamicSection(elf); - AdjustDynamicSectionForHole(dynamic_section, hole_start, hole_size, relocations_type); -} - -// Find the first slot in a dynamics array with the given tag. The array -// always ends with a free (unused) element, and which we exclude from the -// search. Returns dynamics->size() if not found. -template -static size_t FindDynamicEntry(typename ELF::Sword tag, - std::vector* dynamics) { - // Loop until the penultimate entry. We exclude the end sentinel. - for (size_t i = 0; i < dynamics->size() - 1; ++i) { - if (dynamics->at(i).d_tag == tag) { - return i; - } - } - - // The tag was not found. - return dynamics->size(); -} - -// Replace dynamic entry. -template -static void ReplaceDynamicEntry(typename ELF::Sword tag, - const typename ELF::Dyn& dyn, - std::vector* dynamics) { - const size_t slot = FindDynamicEntry(tag, dynamics); - if (slot == dynamics->size()) { - LOG(FATAL) << "Dynamic slot is not found for tag=" << tag; - } - - // Replace this entry with the one supplied. - dynamics->at(slot) = dyn; - VLOG(1) << "dynamic[" << slot << "] overwritten with " << dyn.d_tag; -} - -// Remove relative entries from dynamic relocations and write as packed -// data into android packed relocations. -template -bool ElfFile::PackRelocations() { - // Load the ELF file into libelf. - if (!Load()) { - LOG(ERROR) << "Failed to load as ELF"; - return false; - } - - if (relocations_section_ == nullptr) { - // There is nothing to do - return true; - } - - // Retrieve the current dynamic relocations section data. - Elf_Data* data = GetSectionData(relocations_section_); - // we always pack rela, because packed format is pretty much the same - std::vector relocations; - - if (relocations_type_ == REL) { - // Convert data to a vector of relocations. - const typename ELF::Rel* relocations_base = reinterpret_cast(data->d_buf); - ConvertRelArrayToRelaVector(relocations_base, - data->d_size / sizeof(typename ELF::Rel), &relocations); - VLOG(1) << "Relocations : REL"; - } else if (relocations_type_ == RELA) { - // Convert data to a vector of relocations with addends. - const typename ELF::Rela* relocations_base = reinterpret_cast(data->d_buf); - relocations = std::vector( - relocations_base, - relocations_base + data->d_size / sizeof(relocations[0])); - - VLOG(1) << "Relocations : RELA"; - } else { - NOTREACHED(); - } - - return PackTypedRelocations(&relocations); -} - -// Helper for PackRelocations(). Rel type is one of ELF::Rel or ELF::Rela. -template -bool ElfFile::PackTypedRelocations(std::vector* relocations) { - typedef typename ELF::Rela Rela; - - if (has_android_relocations_) { - LOG(INFO) << "Relocation table is already packed"; - return true; - } - - // If no relocations then we have nothing packable. Perhaps - // the shared object has already been packed? - if (relocations->empty()) { - LOG(ERROR) << "No relocations found"; - return false; - } - - const size_t rel_size = - relocations_type_ == RELA ? sizeof(typename ELF::Rela) : sizeof(typename ELF::Rel); - const size_t initial_bytes = relocations->size() * rel_size; - - VLOG(1) << "Unpacked : " << initial_bytes << " bytes"; - std::vector packed; - RelocationPacker packer; - - // Pack relocations: dry run to estimate memory savings. - packer.PackRelocations(*relocations, &packed); - const size_t packed_bytes_estimate = packed.size() * sizeof(packed[0]); - VLOG(1) << "Packed (no padding): " << packed_bytes_estimate << " bytes"; - - if (packed.empty()) { - VLOG(1) << "Too few relocations to pack"; - return true; - } - - // Pre-calculate the size of the hole we will close up when we rewrite - // dynamic relocations. We have to adjust relocation addresses to - // account for this. - typename ELF::Shdr* section_header = ELF::getshdr(relocations_section_); - ssize_t hole_size = initial_bytes - packed_bytes_estimate; - - // hole_size needs to be page_aligned. - hole_size -= hole_size % kPreserveAlignment; - - VLOG(1) << "Compaction : " << hole_size << " bytes"; - - // Adjusting for alignment may have removed any packing benefit. - if (hole_size == 0) { - VLOG(1) << "Too few relocations to pack after alignment"; - return true; - } - - if (hole_size <= 0) { - VLOG(1) << "Packing relocations saves no space"; - return true; - } - - size_t data_padding_bytes = is_padding_relocations_ ? - initial_bytes - packed_bytes_estimate : - initial_bytes - hole_size - packed_bytes_estimate; - - // pad data - std::vector padding(data_padding_bytes, 0); - packed.insert(packed.end(), padding.begin(), padding.end()); - - const void* packed_data = &packed[0]; - - // Run a loopback self-test as a check that packing is lossless. - std::vector unpacked; - packer.UnpackRelocations(packed, &unpacked); - CHECK(unpacked.size() == relocations->size()); - CHECK(!memcmp(&unpacked[0], - &relocations->at(0), - unpacked.size() * sizeof(unpacked[0]))); - - // Rewrite the current dynamic relocations section with packed one then shrink it to size. - const size_t bytes = packed.size() * sizeof(packed[0]); - ResizeSection(elf_, relocations_section_, bytes, - relocations_type_ == REL ? SHT_ANDROID_REL : SHT_ANDROID_RELA, relocations_type_); - RewriteSectionData(relocations_section_, packed_data, bytes); - - // TODO (dimitry): fix string table and replace .rel.dyn/plt with .android.rel.dyn/plt - - // Rewrite .dynamic and rename relocation tags describing the packed android - // relocations. - Elf_Data* data = GetSectionData(dynamic_section_); - const typename ELF::Dyn* dynamic_base = reinterpret_cast(data->d_buf); - std::vector dynamics( - dynamic_base, - dynamic_base + data->d_size / sizeof(dynamics[0])); - section_header = ELF::getshdr(relocations_section_); - { - typename ELF::Dyn dyn; - dyn.d_tag = relocations_type_ == REL ? DT_ANDROID_REL : DT_ANDROID_RELA; - dyn.d_un.d_ptr = section_header->sh_addr; - ReplaceDynamicEntry(relocations_type_ == REL ? DT_REL : DT_RELA, dyn, &dynamics); - } - { - typename ELF::Dyn dyn; - dyn.d_tag = relocations_type_ == REL ? DT_ANDROID_RELSZ : DT_ANDROID_RELASZ; - dyn.d_un.d_val = section_header->sh_size; - ReplaceDynamicEntry(relocations_type_ == REL ? DT_RELSZ : DT_RELASZ, dyn, &dynamics); - } - - const void* dynamics_data = &dynamics[0]; - const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]); - RewriteSectionData(dynamic_section_, dynamics_data, dynamics_bytes); - - Flush(); - return true; -} - -// Find packed relative relocations in the packed android relocations -// section, unpack them, and rewrite the dynamic relocations section to -// contain unpacked data. -template -bool ElfFile::UnpackRelocations() { - // Load the ELF file into libelf. - if (!Load()) { - LOG(ERROR) << "Failed to load as ELF"; - return false; - } - - if (relocations_section_ == nullptr) { - // There is nothing to do - return true; - } - - typename ELF::Shdr* section_header = ELF::getshdr(relocations_section_); - // Retrieve the current packed android relocations section data. - Elf_Data* data = GetSectionData(relocations_section_); - - // Convert data to a vector of bytes. - const uint8_t* packed_base = reinterpret_cast(data->d_buf); - std::vector packed( - packed_base, - packed_base + data->d_size / sizeof(packed[0])); - - if ((section_header->sh_type == SHT_ANDROID_RELA || section_header->sh_type == SHT_ANDROID_REL) && - packed.size() > 3 && - packed[0] == 'A' && - packed[1] == 'P' && - packed[2] == 'S' && - packed[3] == '2') { - LOG(INFO) << "Relocations : " << (relocations_type_ == REL ? "REL" : "RELA"); - } else { - LOG(ERROR) << "Packed relocations not found (not packed?)"; - return false; - } - - return UnpackTypedRelocations(packed); -} - -// Helper for UnpackRelocations(). Rel type is one of ELF::Rel or ELF::Rela. -template -bool ElfFile::UnpackTypedRelocations(const std::vector& packed) { - // Unpack the data to re-materialize the relative relocations. - const size_t packed_bytes = packed.size() * sizeof(packed[0]); - LOG(INFO) << "Packed : " << packed_bytes << " bytes"; - std::vector unpacked_relocations; - RelocationPacker packer; - packer.UnpackRelocations(packed, &unpacked_relocations); - - const size_t relocation_entry_size = - relocations_type_ == REL ? sizeof(typename ELF::Rel) : sizeof(typename ELF::Rela); - const size_t unpacked_bytes = unpacked_relocations.size() * relocation_entry_size; - LOG(INFO) << "Unpacked : " << unpacked_bytes << " bytes"; - - // Retrieve the current dynamic relocations section data. - Elf_Data* data = GetSectionData(relocations_section_); - - LOG(INFO) << "Relocations : " << unpacked_relocations.size() << " entries"; - - // If we found the same number of null relocation entries in the dynamic - // relocations section as we hold as unpacked relative relocations, then - // this is a padded file. - - const bool is_padded = packed_bytes == unpacked_bytes; - - // Unless padded, pre-apply relative relocations to account for the - // hole, and pre-adjust all relocation offsets accordingly. - typename ELF::Shdr* section_header = ELF::getshdr(relocations_section_); - - if (!is_padded) { - LOG(INFO) << "Expansion : " << unpacked_bytes - packed_bytes << " bytes"; - } - - // Rewrite the current dynamic relocations section with unpacked version of - // relocations. - const void* section_data = nullptr; - std::vector unpacked_rel_relocations; - if (relocations_type_ == RELA) { - section_data = &unpacked_relocations[0]; - } else if (relocations_type_ == REL) { - ConvertRelaVectorToRelVector(unpacked_relocations, &unpacked_rel_relocations); - section_data = &unpacked_rel_relocations[0]; - } else { - NOTREACHED(); - } - - ResizeSection(elf_, relocations_section_, unpacked_bytes, - relocations_type_ == REL ? SHT_REL : SHT_RELA, relocations_type_); - RewriteSectionData(relocations_section_, section_data, unpacked_bytes); - - // Rewrite .dynamic to remove two tags describing packed android relocations. - data = GetSectionData(dynamic_section_); - const typename ELF::Dyn* dynamic_base = reinterpret_cast(data->d_buf); - std::vector dynamics( - dynamic_base, - dynamic_base + data->d_size / sizeof(dynamics[0])); - { - typename ELF::Dyn dyn; - dyn.d_tag = relocations_type_ == REL ? DT_REL : DT_RELA; - dyn.d_un.d_ptr = section_header->sh_addr; - ReplaceDynamicEntry(relocations_type_ == REL ? DT_ANDROID_REL : DT_ANDROID_RELA, - dyn, &dynamics); - } - - { - typename ELF::Dyn dyn; - dyn.d_tag = relocations_type_ == REL ? DT_RELSZ : DT_RELASZ; - dyn.d_un.d_val = section_header->sh_size; - ReplaceDynamicEntry(relocations_type_ == REL ? DT_ANDROID_RELSZ : DT_ANDROID_RELASZ, - dyn, &dynamics); - } - - const void* dynamics_data = &dynamics[0]; - const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]); - RewriteSectionData(dynamic_section_, dynamics_data, dynamics_bytes); - - Flush(); - return true; -} - -// Flush rewritten shared object file data. -template -void ElfFile::Flush() { - // Flag all ELF data held in memory as needing to be written back to the - // file, and tell libelf that we have controlled the file layout. - elf_flagelf(elf_, ELF_C_SET, ELF_F_DIRTY); - elf_flagelf(elf_, ELF_C_SET, ELF_F_LAYOUT); - - // Write ELF data back to disk. - const off_t file_bytes = elf_update(elf_, ELF_C_WRITE); - if (file_bytes == -1) { - LOG(ERROR) << "elf_update failed: " << elf_errmsg(elf_errno()); - } - - CHECK(file_bytes > 0); - VLOG(1) << "elf_update returned: " << file_bytes; - - // Clean up libelf, and truncate the output file to the number of bytes - // written by elf_update(). - elf_end(elf_); - elf_ = NULL; - const int truncate = ftruncate(fd_, file_bytes); - CHECK(truncate == 0); -} - -template -void ElfFile::ConvertRelArrayToRelaVector(const typename ELF::Rel* rel_array, - size_t rel_array_size, - std::vector* rela_vector) { - for (size_t i = 0; ipush_back(rela); - } -} - -template -void ElfFile::ConvertRelaVectorToRelVector(const std::vector& rela_vector, - std::vector* rel_vector) { - for (auto rela : rela_vector) { - typename ELF::Rel rel; - rel.r_offset = rela.r_offset; - rel.r_info = rela.r_info; - CHECK(rela.r_addend == 0); - rel_vector->push_back(rel); - } -} - -template class ElfFile; -template class ElfFile; - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/elf_file.h b/tools/relocation_packer/src/elf_file.h deleted file mode 100644 index d6acc76b7..000000000 --- a/tools/relocation_packer/src/elf_file.h +++ /dev/null @@ -1,121 +0,0 @@ -// 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. - -// ELF shared object file updates handler. -// -// Provides functions to pack relocations in the .rel.dyn or .rela.dyn -// sections, and unpack to return the file to its pre-packed state. -// -// SetPadding() causes PackRelocations() to pad .rel.dyn or .rela.dyn with -// NONE-type entries rather than cutting a hole out of the shared object -// file. This keeps all load addresses and offsets constant, and enables -// easier debugging and testing. -// -// A packed shared object file is shorter than its non-packed original. -// Unpacking a packed file restores the file to its non-packed state. - -#ifndef TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ -#define TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ - -#include -#include - -#include "elf.h" -#include "libelf.h" -#include "packer.h" - -namespace relocation_packer { - -// An ElfFile reads shared objects, and shuttles relative relocations -// between .rel.dyn or .rela.dyn and .android.rel.dyn or .android.rela.dyn -// sections. -template -class ElfFile { - public: - explicit ElfFile(int fd) - : fd_(fd), is_padding_relocations_(false), elf_(NULL), - relocations_section_(NULL), dynamic_section_(NULL), - relocations_type_(NONE), has_android_relocations_(false) {} - ~ElfFile() {} - - // Set padding mode. When padding, PackRelocations() will not shrink - // the .rel.dyn or .rela.dyn section, but instead replace relative with - // NONE-type entries. - // |flag| is true to pad .rel.dyn or .rela.dyn, false to shrink it. - inline void SetPadding(bool flag) { is_padding_relocations_ = flag; } - - // Transfer relative relocations from .rel.dyn or .rela.dyn to a packed - // representation in .android.rel.dyn or .android.rela.dyn. Returns true - // on success. - bool PackRelocations(); - - // Transfer relative relocations from a packed representation in - // .android.rel.dyn or .android.rela.dyn to .rel.dyn or .rela.dyn. Returns - // true on success. - bool UnpackRelocations(); - - private: - enum relocations_type_t { - NONE = 0, REL, RELA - }; - - // Load a new ElfFile from a filedescriptor. If flushing, the file must - // be open for read/write. Returns true on successful ELF file load. - // |fd| is an open file descriptor for the shared object. - bool Load(); - - // Templated packer, helper for PackRelocations(). Rel type is one of - // ELF::Rel or ELF::Rela. - bool PackTypedRelocations(std::vector* relocations); - - // Templated unpacker, helper for UnpackRelocations(). Rel type is one of - // ELF::Rel or ELF::Rela. - bool UnpackTypedRelocations(const std::vector& packed); - - // Write ELF file changes. - void Flush(); - - void AdjustRelativeRelocationTargets(typename ELF::Off hole_start, - ssize_t hole_size, - std::vector* relocations); - - static void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size, - typename ELF::Word new_sh_type, relocations_type_t relocations_type); - - static void AdjustDynamicSectionForHole(Elf_Scn* dynamic_section, - typename ELF::Off hole_start, - ssize_t hole_size, - relocations_type_t relocations_type); - - static void ConvertRelArrayToRelaVector(const typename ELF::Rel* rel_array, size_t rel_array_size, - std::vector* rela_vector); - - static void ConvertRelaVectorToRelVector(const std::vector& rela_vector, - std::vector* rel_vector); - - - // File descriptor opened on the shared object. - int fd_; - - // If set, pad rather than shrink .rel.dyn or .rela.dyn. Primarily for - // debugging, allows packing to be checked without affecting load addresses. - bool is_padding_relocations_; - - // Libelf handle, assigned by Load(). - Elf* elf_; - - // Sections that we manipulate, assigned by Load(). - Elf_Scn* relocations_section_; - Elf_Scn* dynamic_section_; - - // Relocation type found, assigned by Load(). - relocations_type_t relocations_type_; - - // Elf-file has android relocations section - bool has_android_relocations_; -}; - -} // namespace relocation_packer - -#endif // TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ diff --git a/tools/relocation_packer/src/elf_file_unittest.cc b/tools/relocation_packer/src/elf_file_unittest.cc deleted file mode 100644 index d5c891890..000000000 --- a/tools/relocation_packer/src/elf_file_unittest.cc +++ /dev/null @@ -1,218 +0,0 @@ -// 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 "elf_file.h" - -#include -#include -#include -#include -#include -#include "debug.h" -#include "elf_traits.h" -#include "gtest/gtest.h" - -namespace { - -void GetDataFilePath(const char* name, std::string* path) { - std::string data_dir; - - const char* bindir = getenv("bindir"); - if (bindir) { - data_dir = std::string(bindir); - } else { - char path[PATH_MAX]; - memset(path, 0, sizeof(path)); - ASSERT_NE(-1, readlink("/proc/self/exe", path, sizeof(path) - 1)); - - data_dir = std::string(path); - size_t pos = data_dir.rfind('/'); - ASSERT_NE(std::string::npos, pos); - - data_dir.erase(pos); - } - - *path = data_dir + "/" + name; -} - -void OpenRelocsTestFile(const char* name, FILE** stream) { - std::string path; - GetDataFilePath(name, &path); - - FILE* testfile = fopen(path.c_str(), "rb"); - ASSERT_FALSE(testfile == NULL) << "Error opening '" << path << "'"; - - FILE* temporary = tmpfile(); - ASSERT_FALSE(temporary == NULL); - - static const size_t buffer_size = 4096; - unsigned char buffer[buffer_size]; - - size_t bytes; - do { - bytes = fread(buffer, 1, sizeof(buffer), testfile); - ASSERT_EQ(bytes, fwrite(buffer, 1, bytes, temporary)); - } while (bytes > 0); - - ASSERT_EQ(0, fclose(testfile)); - ASSERT_EQ(0, fseek(temporary, 0, SEEK_SET)); - ASSERT_EQ(0, lseek(fileno(temporary), 0, SEEK_SET)); - - *stream = temporary; -} - -void OpenRelocsTestFiles(const std::string& arch, FILE** relocs_so, FILE** packed_relocs_so) { - const std::string base = std::string("elf_file_unittest_relocs_") + arch; - const std::string relocs = base + ".so"; - const std::string packed_relocs = base + "_packed.so"; - - OpenRelocsTestFile(relocs.c_str(), relocs_so); - OpenRelocsTestFile(packed_relocs.c_str(), packed_relocs_so); -} - -void CloseRelocsTestFile(FILE* temporary) { - fclose(temporary); -} - -void CloseRelocsTestFiles(FILE* relocs_so, FILE* packed_relocs_so) { - CloseRelocsTestFile(relocs_so); - CloseRelocsTestFile(packed_relocs_so); -} - -void CheckFileContentsEqual(FILE* first, FILE* second) { - ASSERT_EQ(0, fseek(first, 0, SEEK_SET)); - ASSERT_EQ(0, fseek(second, 0, SEEK_SET)); - - static const size_t buffer_size = 4096; - unsigned char first_buffer[buffer_size]; - unsigned char second_buffer[buffer_size]; - - do { - size_t first_read = fread(first_buffer, 1, sizeof(first_buffer), first); - size_t second_read = fread(second_buffer, 1, sizeof(second_buffer), second); - - EXPECT_EQ(first_read, second_read); - EXPECT_EQ(0, memcmp(first_buffer, second_buffer, first_read)); - } while (!feof(first) && !feof(second)); - - EXPECT_TRUE(feof(first) && feof(second)); -} - -template -static void ProcessUnpack(FILE* relocs_so, FILE* packed_relocs_so) { - relocation_packer::ElfFile elf_file(fileno(packed_relocs_so)); - - // Ensure packing already packed elf-file does not fail the build. - EXPECT_TRUE(elf_file.PackRelocations()); - - // Unpack golden relocations, and check files are now identical. - EXPECT_TRUE(elf_file.UnpackRelocations()); - CheckFileContentsEqual(packed_relocs_so, relocs_so); - - CloseRelocsTestFiles(relocs_so, packed_relocs_so); -} - -static void RunUnpackRelocationsTestFor(const std::string& arch) { - ASSERT_NE(static_cast(EV_NONE), elf_version(EV_CURRENT)); - - FILE* relocs_so = NULL; - FILE* packed_relocs_so = NULL; - OpenRelocsTestFiles(arch, &relocs_so, &packed_relocs_so); - - if (relocs_so != NULL && packed_relocs_so != NULL) { - // lets detect elf class - ASSERT_EQ(0, fseek(relocs_so, EI_CLASS, SEEK_SET)) - << "Invalid file length: " << strerror(errno); - uint8_t elf_class = 0; - ASSERT_EQ(1U, fread(&elf_class, 1, 1, relocs_so)); - ASSERT_EQ(0, fseek(relocs_so, 0, SEEK_SET)); - if (elf_class == ELFCLASS32) { - ProcessUnpack(relocs_so, packed_relocs_so); - } else { - ProcessUnpack(relocs_so, packed_relocs_so); - } - } -} - -template -static void ProcessPack(FILE* relocs_so, FILE* packed_relocs_so) { - relocation_packer::ElfFile elf_file(fileno(relocs_so)); - - // Ensure unpacking fails (not packed). - EXPECT_FALSE(elf_file.UnpackRelocations()); - - // Pack relocations, and check files are now identical. - EXPECT_TRUE(elf_file.PackRelocations()); - CheckFileContentsEqual(relocs_so, packed_relocs_so); - - CloseRelocsTestFiles(relocs_so, packed_relocs_so); -} - -static void RunPackRelocationsTestFor(const std::string& arch) { - ASSERT_NE(static_cast(EV_NONE), elf_version(EV_CURRENT)); - - FILE* relocs_so = NULL; - FILE* packed_relocs_so = NULL; - OpenRelocsTestFiles(arch, &relocs_so, &packed_relocs_so); - - if (relocs_so != NULL && packed_relocs_so != NULL) { - // lets detect elf class - ASSERT_EQ(0, fseek(packed_relocs_so, EI_CLASS, SEEK_SET)) - << "Invalid file length: " << strerror(errno); - uint8_t elf_class = 0; - ASSERT_EQ(1U, fread(&elf_class, 1, 1, packed_relocs_so)); - fseek(packed_relocs_so, 0, SEEK_SET); - if (elf_class == ELFCLASS32) { - ProcessPack(relocs_so, packed_relocs_so); - } else { - ProcessPack(relocs_so, packed_relocs_so); - } - } -} - -} // namespace - -namespace relocation_packer { - -TEST(ElfFile, PackRelocationsArm32) { - RunPackRelocationsTestFor("arm32"); -} - -TEST(ElfFile, PackRelocationsArm64) { - RunPackRelocationsTestFor("arm64"); -} - -TEST(ElfFile, PackRelocationsMips32) { - RunPackRelocationsTestFor("mips32"); -} - -TEST(ElfFile, PackRelocationsIa32) { - RunPackRelocationsTestFor("ia32"); -} - -TEST(ElfFile, PackRelocationsX64) { - RunPackRelocationsTestFor("x64"); -} - -TEST(ElfFile, UnpackRelocationsArm32) { - RunUnpackRelocationsTestFor("arm32"); -} - -TEST(ElfFile, UnpackRelocationsArm64) { - RunUnpackRelocationsTestFor("arm64"); -} - -TEST(ElfFile, UnpackRelocationsMips32) { - RunUnpackRelocationsTestFor("mips32"); -} - -TEST(ElfFile, UnpackRelocationsIa32) { - RunUnpackRelocationsTestFor("ia32"); -} - -TEST(ElfFile, UnpackRelocationsX64) { - RunUnpackRelocationsTestFor("x64"); -} - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/elf_traits.h b/tools/relocation_packer/src/elf_traits.h deleted file mode 100644 index 3e282b276..000000000 --- a/tools/relocation_packer/src/elf_traits.h +++ /dev/null @@ -1,68 +0,0 @@ -// 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. - -// Target-specific ELF type traits. - -#ifndef TOOLS_RELOCATION_PACKER_SRC_ELF_TRAITS_H_ -#define TOOLS_RELOCATION_PACKER_SRC_ELF_TRAITS_H_ - -#include "elf.h" -#include "libelf.h" - -#if !defined(DT_MIPS_RLD_MAP_REL) -#define DT_MIPS_RLD_MAP_REL 0x70000035 -#endif - -// ELF is a traits structure used to provide convenient aliases for -// 32/64 bit Elf types and functions, depending on the target file. - -struct ELF32_traits { - typedef Elf32_Addr Addr; - typedef Elf32_Dyn Dyn; - typedef Elf32_Ehdr Ehdr; - typedef Elf32_Off Off; - typedef Elf32_Phdr Phdr; - typedef Elf32_Rel Rel; - typedef Elf32_Rela Rela; - typedef Elf32_Shdr Shdr; - typedef Elf32_Sword Sword; - typedef Elf32_Sxword Sxword; - typedef Elf32_Sym Sym; - typedef Elf32_Word Word; - typedef Elf32_Xword Xword; - typedef Elf32_Half Half; - - static inline Ehdr* getehdr(Elf* elf) { return elf32_getehdr(elf); } - static inline Phdr* getphdr(Elf* elf) { return elf32_getphdr(elf); } - static inline Shdr* getshdr(Elf_Scn* scn) { return elf32_getshdr(scn); } - static inline Word elf_r_type(Word info) { return ELF32_R_TYPE(info); } - static inline int elf_st_type(uint8_t info) { return ELF32_ST_TYPE(info); } - static inline Word elf_r_sym(Word info) { return ELF32_R_SYM(info); } -}; - -struct ELF64_traits { - typedef Elf64_Addr Addr; - typedef Elf64_Dyn Dyn; - typedef Elf64_Ehdr Ehdr; - typedef Elf64_Off Off; - typedef Elf64_Phdr Phdr; - typedef Elf64_Rel Rel; - typedef Elf64_Rela Rela; - typedef Elf64_Shdr Shdr; - typedef Elf64_Sword Sword; - typedef Elf64_Sxword Sxword; - typedef Elf64_Sym Sym; - typedef Elf64_Word Word; - typedef Elf64_Xword Xword; - typedef Elf64_Half Half; - - static inline Ehdr* getehdr(Elf* elf) { return elf64_getehdr(elf); } - static inline Phdr* getphdr(Elf* elf) { return elf64_getphdr(elf); } - static inline Shdr* getshdr(Elf_Scn* scn) { return elf64_getshdr(scn); } - static inline Xword elf_r_type(Xword info) { return ELF64_R_TYPE(info); } - static inline int elf_st_type(uint8_t info) { return ELF64_ST_TYPE(info); } - static inline Word elf_r_sym(Xword info) { return ELF64_R_SYM(info); } -}; - -#endif // TOOLS_RELOCATION_PACKER_SRC_ELF_TRAITS_H_ diff --git a/tools/relocation_packer/src/main.cc b/tools/relocation_packer/src/main.cc deleted file mode 100644 index 15890434a..000000000 --- a/tools/relocation_packer/src/main.cc +++ /dev/null @@ -1,150 +0,0 @@ -// 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. - -// Tool to pack and unpack relative relocations in a shared library. -// -// Invoke with -v to trace actions taken when packing or unpacking. -// Invoke with -p to pad removed relocations with R_*_NONE. Suppresses -// shrinking of .rel.dyn. -// See PrintUsage() below for full usage details. -// -// NOTE: Breaks with libelf 0.152, which is buggy. libelf 0.158 works. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "elf_file.h" -#include "elf_traits.h" -#include "libelf.h" - -#include - -static void PrintUsage(const char* argv0) { - std::string temporary = argv0; - const size_t last_slash = temporary.find_last_of("/"); - if (last_slash != temporary.npos) { - temporary.erase(0, last_slash + 1); - } - const char* basename = temporary.c_str(); - - printf( - "Usage: %s [-u] [-v] [-p] file\n\n" - "Pack or unpack relative relocations in a shared library.\n\n" - " -u, --unpack unpack previously packed relative relocations\n" - " -v, --verbose trace object file modifications (for debugging)\n" - " -p, --pad do not shrink relocations, but pad (for debugging)\n\n", - basename); - - printf( - "Debug sections are not handled, so packing should not be used on\n" - "shared libraries compiled for debugging or otherwise unstripped.\n"); -} - -int main(int argc, char* argv[]) { - bool is_unpacking = false; - bool is_verbose = false; - bool is_padding = false; - - static const option options[] = { - {"unpack", 0, 0, 'u'}, {"verbose", 0, 0, 'v'}, {"pad", 0, 0, 'p'}, - {"help", 0, 0, 'h'}, {NULL, 0, 0, 0} - }; - bool has_options = true; - while (has_options) { - int c = getopt_long(argc, argv, "uvph", options, NULL); - switch (c) { - case 'u': - is_unpacking = true; - break; - case 'v': - is_verbose = true; - break; - case 'p': - is_padding = true; - break; - case 'h': - PrintUsage(argv[0]); - return 0; - case '?': - LOG(INFO) << "Try '" << argv[0] << " --help' for more information."; - return 1; - case -1: - has_options = false; - break; - default: - NOTREACHED(); - return 1; - } - } - if (optind != argc - 1) { - LOG(INFO) << "Try '" << argv[0] << " --help' for more information."; - return 1; - } - - if (elf_version(EV_CURRENT) == EV_NONE) { - LOG(WARNING) << "Elf Library is out of date!"; - } - - const char* file = argv[argc - 1]; - android::base::unique_fd fd(open(file, O_RDWR)); - if (fd.get() == -1) { - LOG(ERROR) << file << ": " << strerror(errno); - return 1; - } - - if (is_verbose) - relocation_packer::Logger::SetVerbose(1); - - // We need to detect elf class in order to create - // correct implementation - uint8_t e_ident[EI_NIDENT]; - if (TEMP_FAILURE_RETRY(read(fd.get(), e_ident, EI_NIDENT)) != EI_NIDENT) { - LOG(ERROR) << file << ": failed to read elf header:" << strerror(errno); - return 1; - } - - if (TEMP_FAILURE_RETRY(lseek(fd.get(), 0, SEEK_SET)) != 0) { - LOG(ERROR) << file << ": lseek to 0 failed:" << strerror(errno); - return 1; - } - - bool status = false; - - if (e_ident[EI_CLASS] == ELFCLASS32) { - relocation_packer::ElfFile elf_file(fd.get()); - elf_file.SetPadding(is_padding); - - if (is_unpacking) { - status = elf_file.UnpackRelocations(); - } else { - status = elf_file.PackRelocations(); - } - } else if (e_ident[EI_CLASS] == ELFCLASS64) { - relocation_packer::ElfFile elf_file(fd.get()); - elf_file.SetPadding(is_padding); - - if (is_unpacking) { - status = elf_file.UnpackRelocations(); - } else { - status = elf_file.PackRelocations(); - } - } else { - LOG(ERROR) << file << ": unknown ELFCLASS: " << e_ident[EI_CLASS]; - return 1; - } - - if (!status) { - LOG(ERROR) << file << ": failed to pack/unpack file"; - return 1; - } - - return 0; -} diff --git a/tools/relocation_packer/src/packer.cc b/tools/relocation_packer/src/packer.cc deleted file mode 100644 index 433611faa..000000000 --- a/tools/relocation_packer/src/packer.cc +++ /dev/null @@ -1,67 +0,0 @@ -// 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 "packer.h" - -#include - -#include "debug.h" -#include "delta_encoder.h" -#include "elf_traits.h" -#include "sleb128.h" - -namespace relocation_packer { - -// Pack relocations into a group encoded packed representation. -template -void RelocationPacker::PackRelocations(const std::vector& relocations, - std::vector* packed) { - // Run-length encode. - std::vector packed_words; - RelocationDeltaCodec codec; - codec.Encode(relocations, &packed_words); - - // If insufficient data do nothing. - if (packed_words.empty()) - return; - - Sleb128Encoder sleb128_encoder; - - std::vector sleb128_packed; - - sleb128_encoder.EnqueueAll(packed_words); - sleb128_encoder.GetEncoding(&sleb128_packed); - - packed->push_back('A'); - packed->push_back('P'); - packed->push_back('S'); - packed->push_back('2'); - packed->insert(packed->end(), sleb128_packed.begin(), sleb128_packed.end()); -} - -// Unpack relative relocations from a run-length encoded packed -// representation. -template -void RelocationPacker::UnpackRelocations( - const std::vector& packed, - std::vector* relocations) { - - std::vector packed_words; - CHECK(packed.size() > 4 && - packed[0] == 'A' && - packed[1] == 'P' && - packed[2] == 'S' && - packed[3] == '2'); - - Sleb128Decoder decoder(packed, 4); - decoder.DequeueAll(&packed_words); - - RelocationDeltaCodec codec; - codec.Decode(packed_words, relocations); -} - -template class RelocationPacker; -template class RelocationPacker; - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/packer.h b/tools/relocation_packer/src/packer.h deleted file mode 100644 index 63f50e249..000000000 --- a/tools/relocation_packer/src/packer.h +++ /dev/null @@ -1,37 +0,0 @@ -// 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. - -// Pack relative relocations into a more compact form. - -#ifndef TOOLS_RELOCATION_PACKER_SRC_PACKER_H_ -#define TOOLS_RELOCATION_PACKER_SRC_PACKER_H_ - -#include -#include - -#include "elf.h" - -namespace relocation_packer { - -// A RelocationPacker packs vectors of relocations into more -// compact forms, and unpacks them to reproduce the pre-packed data. -template -class RelocationPacker { - public: - // Pack relocations into a more compact form. - // |relocations| is a vector of relocation structs. - // |packed| is the vector of packed bytes into which relocations are packed. - static void PackRelocations(const std::vector& relocations, - std::vector* packed); - - // Unpack relocations from their more compact form. - // |packed| is the vector of packed relocations. - // |relocations| is a vector of unpacked relocation structs. - static void UnpackRelocations(const std::vector& packed, - std::vector* relocations); -}; - -} // namespace relocation_packer - -#endif // TOOLS_RELOCATION_PACKER_SRC_PACKER_H_ diff --git a/tools/relocation_packer/src/packer_unittest.cc b/tools/relocation_packer/src/packer_unittest.cc deleted file mode 100644 index 424b92cd0..000000000 --- a/tools/relocation_packer/src/packer_unittest.cc +++ /dev/null @@ -1,300 +0,0 @@ -// 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 "packer.h" - -#include -#include "elf.h" -#include "elf_traits.h" -#include "gtest/gtest.h" - - -template -static void AddRelocation(typename ELF::Addr addr, - typename ELF::Xword info, - typename ELF::Sxword addend, - std::vector* relocations) { - typename ELF::Rela relocation; - relocation.r_offset = addr; - relocation.r_info = info; - relocation.r_addend = addend; - - relocations->push_back(relocation); -} - -template -static bool CheckRelocation(typename ELF::Addr addr, - typename ELF::Xword info, - typename ELF::Sxword addend, - const typename ELF::Rela& relocation) { - return relocation.r_offset == addr && - relocation.r_info == info && - relocation.r_addend == addend; -} - -namespace relocation_packer { - -template -static void DoPackNoAddend() { - std::vector relocations; - std::vector packed; - bool is_32 = sizeof(typename ELF::Addr) == 4; - // Initial relocation. - AddRelocation(0xd1ce0000, 0x11, 0, &relocations); - // Two more relocations, 4 byte deltas. - AddRelocation(0xd1ce0004, 0x11, 0, &relocations); - AddRelocation(0xd1ce0008, 0x11, 0, &relocations); - // Three more relocations, 8 byte deltas. - AddRelocation(0xd1ce0010, 0x11, 0, &relocations); - AddRelocation(0xd1ce0018, 0x11, 0, &relocations); - AddRelocation(0xd1ce0020, 0x11, 0, &relocations); - - RelocationPacker packer; - - packed.clear(); - packer.PackRelocations(relocations, &packed); - - ASSERT_EQ(18U, packed.size()); - // Identifier. - size_t ndx = 0; - EXPECT_EQ('A', packed[ndx++]); - EXPECT_EQ('P', packed[ndx++]); - EXPECT_EQ('S', packed[ndx++]); - EXPECT_EQ('2', packed[ndx++]); - // relocation count - EXPECT_EQ(6, packed[ndx++]); - // base relocation = 0xd1cdfffc -> fc, ff, b7, 8e, 7d/0d (32/64bit) - EXPECT_EQ(0xfc, packed[ndx++]); - EXPECT_EQ(0xff, packed[ndx++]); - EXPECT_EQ(0xb7, packed[ndx++]); - EXPECT_EQ(0x8e, packed[ndx++]); - EXPECT_EQ(is_32 ? 0x7d : 0x0d, packed[ndx++]); - // first group - EXPECT_EQ(3, packed[ndx++]); // size - EXPECT_EQ(3, packed[ndx++]); // flags - EXPECT_EQ(4, packed[ndx++]); // r_offset_delta - EXPECT_EQ(0x11, packed[ndx++]); // r_info - // second group - EXPECT_EQ(3, packed[ndx++]); // size - EXPECT_EQ(3, packed[ndx++]); // flags - EXPECT_EQ(8, packed[ndx++]); // r_offset_delta - EXPECT_EQ(0x11, packed[ndx++]); // r_info - - EXPECT_EQ(ndx, packed.size()); -} - -TEST(Packer, PackNoAddend32) { - DoPackNoAddend(); -} - -TEST(Packer, PackNoAddend64) { - DoPackNoAddend(); -} - -template -static void DoUnpackNoAddend() { - std::vector relocations; - std::vector packed; - bool is_32 = sizeof(typename ELF::Addr) == 4; - packed.push_back('A'); - packed.push_back('P'); - packed.push_back('S'); - packed.push_back('2'); - // relocation count - packed.push_back(6); - // base relocation = 0xd1cdfffc -> fc, ff, b7, 8e, 7d/0d (32/64bit) - packed.push_back(0xfc); - packed.push_back(0xff); - packed.push_back(0xb7); - packed.push_back(0x8e); - packed.push_back(is_32 ? 0x7d : 0x0d); - // first group - packed.push_back(3); // size - packed.push_back(3); // flags - packed.push_back(4); // r_offset_delta - packed.push_back(0x11); // r_info - // second group - packed.push_back(3); // size - packed.push_back(3); // flags - packed.push_back(8); // r_offset_delta - packed.push_back(0x11); // r_info - - RelocationPacker packer; - packer.UnpackRelocations(packed, &relocations); - - size_t ndx = 0; - EXPECT_EQ(6U, relocations.size()); - EXPECT_TRUE(CheckRelocation(0xd1ce0000, 0x11, 0, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0004, 0x11, 0, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0008, 0x11, 0, relocations[ndx++])); - - EXPECT_TRUE(CheckRelocation(0xd1ce0010, 0x11, 0, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0018, 0x11, 0, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0020, 0x11, 0, relocations[ndx++])); - - EXPECT_EQ(ndx, relocations.size()); -} - -TEST(Packer, UnpackNoAddend32) { - DoUnpackNoAddend(); -} - -TEST(Packer, UnpackNoAddend64) { - DoUnpackNoAddend(); -} - -template -static void DoPackWithAddend() { - std::vector relocations; - - // Initial relocation. - AddRelocation(0xd1ce0000, 0x01, 10024, &relocations); - // Two more relocations, 4 byte offset deltas, 12 byte addend deltas. - AddRelocation(0xd1ce0004, 0x01, 10012, &relocations); - AddRelocation(0xd1ce0008, 0x01, 10024, &relocations); - // Three more relocations, 8 byte deltas, -24 byte addend deltas. - AddRelocation(0xd1ce0010, 0x01, 10000, &relocations); - AddRelocation(0xd1ce0018, 0x01, 9976, &relocations); - AddRelocation(0xd1ce0020, 0x01, 9952, &relocations); - - std::vector packed; - - RelocationPacker packer; - - packed.clear(); - packer.PackRelocations(relocations, &packed); - - EXPECT_EQ(26U, packed.size()); - size_t ndx = 0; - // Identifier. - EXPECT_EQ('A', packed[ndx++]); - EXPECT_EQ('P', packed[ndx++]); - EXPECT_EQ('S', packed[ndx++]); - EXPECT_EQ('2', packed[ndx++]); - // Relocation count - EXPECT_EQ(6U, packed[ndx++]); - // base relocation = 0xd1cdfffc -> fc, ff, b7, 8e, 0d/7d (depending on ELF::Addr) - EXPECT_EQ(0xfc, packed[ndx++]); - EXPECT_EQ(0xff, packed[ndx++]); - EXPECT_EQ(0xb7, packed[ndx++]); - EXPECT_EQ(0x8e, packed[ndx++]); - if (sizeof(typename ELF::Addr) == 8) { - // positive for uint64_t - EXPECT_EQ(0x0d, packed[ndx++]); - } else { - // negative for uint32_t - EXPECT_EQ(0x7d, packed[ndx++]); - } - // group 1 - EXPECT_EQ(0x03, packed[ndx++]); // size - EXPECT_EQ(0x0b, packed[ndx++]); // flags - EXPECT_EQ(0x04, packed[ndx++]); // r_offset_delta - EXPECT_EQ(0x01, packed[ndx++]); // r_info - // group 1 - addend 1: 10024 = 0xa8, 0xce, 0x80 - EXPECT_EQ(0xa8, packed[ndx++]); - EXPECT_EQ(0xce, packed[ndx++]); - EXPECT_EQ(0x00, packed[ndx++]); - // group 1 - addend 2: -12 = 0x74 - EXPECT_EQ(0x74, packed[ndx++]); - // group 1 - addend 3: +12 = 0x0c - EXPECT_EQ(0x0c, packed[ndx++]); - - // group 2 - EXPECT_EQ(0x03, packed[ndx++]); // size - EXPECT_EQ(0x0b, packed[ndx++]); // flags - EXPECT_EQ(0x08, packed[ndx++]); // r_offset_delta - EXPECT_EQ(0x01, packed[ndx++]); // r_info - - // group 2 - addend 1: -24 = 0x68 - EXPECT_EQ(0x68, packed[ndx++]); - // group 2 - addend 2: -24 = 0x68 - EXPECT_EQ(0x68, packed[ndx++]); - // group 2 - addend 3: -24 = 0x68 - EXPECT_EQ(0x68, packed[ndx++]); - - EXPECT_EQ(ndx, packed.size()); -} - -TEST(Packer, PackWithAddend) { - DoPackWithAddend(); - DoPackWithAddend(); -} - -template -static void DoUnpackWithAddend() { - std::vector packed; - // Identifier. - packed.push_back('A'); - packed.push_back('P'); - packed.push_back('S'); - packed.push_back('2'); - // Relocation count - packed.push_back(6U); - // base relocation = 0xd1cdfffc -> fc, ff, b7, 8e, 0d - packed.push_back(0xfc); - packed.push_back(0xff); - packed.push_back(0xb7); - packed.push_back(0x8e); - if (sizeof(typename ELF::Addr) == 8) { - // positive for uint64_t - packed.push_back(0x0d); - } else { - // negative for uint32_t - packed.push_back(0x7d); - } - // group 1 - packed.push_back(0x03); // size - packed.push_back(0x0b); // flags - packed.push_back(0x04); // r_offset_delta - packed.push_back(0x01); // r_info - // group 1 - addend 1: 10024 = 0xa8, 0xce, 0x80 - packed.push_back(0xa8); - packed.push_back(0xce); - packed.push_back(0x00); - // group 1 - addend 2: -12 = 0x74 - packed.push_back(0x74); - // group 1 - addend 3: +12 = 0x0c - packed.push_back(0x0c); - - // group 2 - packed.push_back(0x03); // size - packed.push_back(0x0b); // flags - packed.push_back(0x08); // r_offset_delta - packed.push_back(0x01); // r_info - - // group 2 - addend 1: -24 = 0x68 - packed.push_back(0x68); - // group 2 - addend 2: -24 = 0x68 - packed.push_back(0x68); - // group 2 - addend 3: -24 = 0x68 - packed.push_back(0x68); - - std::vector relocations; - - RelocationPacker packer; - - relocations.clear(); - packer.UnpackRelocations(packed, &relocations); - - EXPECT_EQ(6U, relocations.size()); - size_t ndx = 0; - // Initial relocation. - EXPECT_TRUE(CheckRelocation(0xd1ce0000, 0x01, 10024, relocations[ndx++])); - // Two more relocations, 4 byte offset deltas, 12 byte addend deltas. - EXPECT_TRUE(CheckRelocation(0xd1ce0004, 0x01, 10012, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0008, 0x01, 10024, relocations[ndx++])); - // Three more relocations, 8 byte offset deltas, -24 byte addend deltas. - EXPECT_TRUE(CheckRelocation(0xd1ce0010, 0x01, 10000, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0018, 0x01, 9976, relocations[ndx++])); - EXPECT_TRUE(CheckRelocation(0xd1ce0020, 0x01, 9952, relocations[ndx++])); - - EXPECT_EQ(ndx, relocations.size()); -} - -TEST(Packer, UnpackWithAddend) { - DoUnpackWithAddend(); - DoUnpackWithAddend(); -} - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/sleb128.cc b/tools/relocation_packer/src/sleb128.cc deleted file mode 100644 index 12c21e364..000000000 --- a/tools/relocation_packer/src/sleb128.cc +++ /dev/null @@ -1,131 +0,0 @@ -// 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 "sleb128.h" - -#include -#include -#include - -#include "elf_traits.h" - -namespace { - -template -class uint_traits {}; - -template <> -class uint_traits { - public: - typedef int64_t int_t; -}; - -template <> -class uint_traits { - public: - typedef int32_t int_t; -}; - -} - -namespace relocation_packer { - -// Empty constructor and destructor to silence chromium-style. -template -Sleb128Encoder::Sleb128Encoder() { } - -template -Sleb128Encoder::~Sleb128Encoder() { } - -// Add a single value to the encoding. Values are encoded with variable -// length. The least significant 7 bits of each byte hold 7 bits of data, -// and the most significant bit is set on each byte except the last. The -// value is sign extended up to a multiple of 7 bits (ensuring that the -// most significant bit is zero for a positive number and one for a -// negative number). -template -void Sleb128Encoder::Enqueue(uint_t value) { - typedef typename uint_traits::int_t int_t; - static const size_t size = CHAR_BIT * sizeof(value); - - bool more = true; - const bool negative = static_cast(value) < 0; - - while (more) { - uint8_t byte = value & 127; - value >>= 7; - - // Sign extend if encoding a -ve value. - if (negative) - value |= -(static_cast(1) << (size - 7)); - - // The sign bit of byte is second high order bit. - const bool sign_bit = byte & 64; - if ((value == 0 && !sign_bit) || (value == static_cast(-1) && sign_bit)) - more = false; - else - byte |= 128; - encoding_.push_back(byte); - } -} - -// Add a vector of values to the encoding. -template -void Sleb128Encoder::EnqueueAll(const std::vector& values) { - for (size_t i = 0; i < values.size(); ++i) { - Enqueue(values[i]); - } -} - -// Create a new decoder for the given encoded stream. -template -Sleb128Decoder::Sleb128Decoder(const std::vector& encoding, size_t start_with) { - encoding_ = encoding; - cursor_ = start_with; -} - -// Empty destructor to silence chromium-style. -template -Sleb128Decoder::~Sleb128Decoder() { } - -// Decode and retrieve a single value from the encoding. Consume bytes -// until one without its most significant bit is found, and re-form the -// value from the 7 bit fields of the bytes consumed. -template -uint_t Sleb128Decoder::Dequeue() { - uint_t value = 0; - static const size_t size = CHAR_BIT * sizeof(value); - - size_t shift = 0; - uint8_t byte; - - // Loop until we reach a byte with its high order bit clear. - do { - byte = encoding_[cursor_++]; - value |= (static_cast(byte & 127) << shift); - shift += 7; - } while (byte & 128); - - // The sign bit is second high order bit of the final byte decoded. - // Sign extend if value is -ve and we did not shift all of it. - if (shift < size && (byte & 64)) - value |= -(static_cast(1) << shift); - - return static_cast(value); -} - -// Decode and retrieve all remaining values from the encoding. -template -void Sleb128Decoder::DequeueAll(std::vector* values) { - while (cursor_ < encoding_.size()) { - values->push_back(Dequeue()); - } -} - -template class Sleb128Encoder; -template class Sleb128Encoder; -template class Sleb128Decoder; -template class Sleb128Decoder; - -} // namespace relocation_packer diff --git a/tools/relocation_packer/src/sleb128.h b/tools/relocation_packer/src/sleb128.h deleted file mode 100644 index 3a63f6679..000000000 --- a/tools/relocation_packer/src/sleb128.h +++ /dev/null @@ -1,76 +0,0 @@ -// 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. - -// SLEB128 encoder and decoder for packed relative relocations. -// -// Packed relocations consist of a large number of relatively small -// integer values. Encoding these as LEB128 saves space. -// -// For more on LEB128 see http://en.wikipedia.org/wiki/LEB128. - -#ifndef TOOLS_RELOCATION_PACKER_SRC_SLEB128_H_ -#define TOOLS_RELOCATION_PACKER_SRC_SLEB128_H_ - -#include -#include -#include - -#include "elf_traits.h" - -namespace relocation_packer { - -// Encode packed words as a signed LEB128 byte stream. -template -class Sleb128Encoder { - public: - // Explicit (but empty) constructor and destructor, for chromium-style. - Sleb128Encoder(); - ~Sleb128Encoder(); - - // Add a value to the encoding stream. - // |value| is the signed int to add. - void Enqueue(int_t value); - - // Add a vector of values to the encoding stream. - // |values| is the vector of signed ints to add. - void EnqueueAll(const std::vector& values); - - // Retrieve the encoded representation of the values. - // |encoding| is the returned vector of encoded data. - void GetEncoding(std::vector* encoding) { *encoding = encoding_; } - - private: - // Growable vector holding the encoded LEB128 stream. - std::vector encoding_; -}; - -// Decode a LEB128 byte stream to produce packed words. -template -class Sleb128Decoder { - public: - // Create a new decoder for the given encoded stream. - // |encoding| is the vector of encoded data. - explicit Sleb128Decoder(const std::vector& encoding, size_t start_with); - - // Explicit (but empty) destructor, for chromium-style. - ~Sleb128Decoder(); - - // Retrieve the next value from the encoded stream. - int_t Dequeue(); - - // Retrieve all remaining values from the encoded stream. - // |values| is the vector of decoded data. - void DequeueAll(std::vector* values); - - private: - // Encoded LEB128 stream. - std::vector encoding_; - - // Cursor indicating the current stream retrieval point. - size_t cursor_; -}; - -} // namespace relocation_packer - -#endif // TOOLS_RELOCATION_PACKER_SRC_SLEB128_H_ diff --git a/tools/relocation_packer/src/sleb128_unittest.cc b/tools/relocation_packer/src/sleb128_unittest.cc deleted file mode 100644 index 49a553c2f..000000000 --- a/tools/relocation_packer/src/sleb128_unittest.cc +++ /dev/null @@ -1,166 +0,0 @@ -// 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 "sleb128.h" - -#include -#include "elf_traits.h" -#include "gtest/gtest.h" - -namespace relocation_packer { - -TEST(Sleb128, Encoder64) { - std::vector values; - values.push_back(624485U); - values.push_back(0U); - values.push_back(1U); - values.push_back(63U); - values.push_back(64U); - values.push_back(static_cast(-1)); - values.push_back(static_cast(-624485)); - - Sleb128Encoder encoder; - encoder.EnqueueAll(values); - - encoder.Enqueue(2147483647U); - encoder.Enqueue(static_cast(-2147483648)); - encoder.Enqueue(9223372036854775807ULL); - encoder.Enqueue(static_cast(-9223372036854775807LL - 1)); - - std::vector encoding; - encoder.GetEncoding(&encoding); - - EXPECT_EQ(42u, encoding.size()); - // 624485 - EXPECT_EQ(0xe5, encoding[0]); - EXPECT_EQ(0x8e, encoding[1]); - EXPECT_EQ(0x26, encoding[2]); - // 0 - EXPECT_EQ(0x00, encoding[3]); - // 1 - EXPECT_EQ(0x01, encoding[4]); - // 63 - EXPECT_EQ(0x3f, encoding[5]); - // 64 - EXPECT_EQ(0xc0, encoding[6]); - EXPECT_EQ(0x00, encoding[7]); - // -1 - EXPECT_EQ(0x7f, encoding[8]); - // -624485 - EXPECT_EQ(0x9b, encoding[9]); - EXPECT_EQ(0xf1, encoding[10]); - EXPECT_EQ(0x59, encoding[11]); - // 2147483647 - EXPECT_EQ(0xff, encoding[12]); - EXPECT_EQ(0xff, encoding[13]); - EXPECT_EQ(0xff, encoding[14]); - EXPECT_EQ(0xff, encoding[15]); - EXPECT_EQ(0x07, encoding[16]); - // -2147483648 - EXPECT_EQ(0x80, encoding[17]); - EXPECT_EQ(0x80, encoding[18]); - EXPECT_EQ(0x80, encoding[19]); - EXPECT_EQ(0x80, encoding[20]); - EXPECT_EQ(0x78, encoding[21]); - // 9223372036854775807 - EXPECT_EQ(0xff, encoding[22]); - EXPECT_EQ(0xff, encoding[23]); - EXPECT_EQ(0xff, encoding[24]); - EXPECT_EQ(0xff, encoding[25]); - EXPECT_EQ(0xff, encoding[26]); - EXPECT_EQ(0xff, encoding[27]); - EXPECT_EQ(0xff, encoding[28]); - EXPECT_EQ(0xff, encoding[29]); - EXPECT_EQ(0xff, encoding[30]); - EXPECT_EQ(0x00, encoding[31]); - // -9223372036854775808 - EXPECT_EQ(0x80, encoding[32]); - EXPECT_EQ(0x80, encoding[33]); - EXPECT_EQ(0x80, encoding[34]); - EXPECT_EQ(0x80, encoding[35]); - EXPECT_EQ(0x80, encoding[36]); - EXPECT_EQ(0x80, encoding[37]); - EXPECT_EQ(0x80, encoding[38]); - EXPECT_EQ(0x80, encoding[39]); - EXPECT_EQ(0x80, encoding[40]); - EXPECT_EQ(0x7f, encoding[41]); -} - -TEST(Sleb128, Decoder) { - std::vector encoding; - // 624485 - encoding.push_back(0xe5); - encoding.push_back(0x8e); - encoding.push_back(0x26); - // 0 - encoding.push_back(0x00); - // 1 - encoding.push_back(0x01); - // 63 - encoding.push_back(0x3f); - // 64 - encoding.push_back(0xc0); - encoding.push_back(0x00); - // -1 - encoding.push_back(0x7f); - // -624485 - encoding.push_back(0x9b); - encoding.push_back(0xf1); - encoding.push_back(0x59); - // 2147483647 - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0x07); - // -2147483648 - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x78); - // 9223372036854775807 - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0xff); - encoding.push_back(0x00); - // -9223372036854775808 - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x80); - encoding.push_back(0x7f); - - Sleb128Decoder decoder(encoding, 0); - - EXPECT_EQ(624485U, decoder.Dequeue()); - - std::vector dequeued; - decoder.DequeueAll(&dequeued); - - EXPECT_EQ(10U, dequeued.size()); - EXPECT_EQ(0U, dequeued[0]); - EXPECT_EQ(1U, dequeued[1]); - EXPECT_EQ(63U, dequeued[2]); - EXPECT_EQ(64U, dequeued[3]); - EXPECT_EQ(static_cast(-1), dequeued[4]); - EXPECT_EQ(static_cast(-624485), dequeued[5]); - EXPECT_EQ(2147483647U, dequeued[6]); - EXPECT_EQ(static_cast(-2147483648), dequeued[7]); - EXPECT_EQ(9223372036854775807ULL, dequeued[8]); - EXPECT_EQ(static_cast(-9223372036854775807LL - 1), dequeued[9]); -} - -} // namespace relocation_packer diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs.cc b/tools/relocation_packer/test_data/elf_file_unittest_relocs.cc deleted file mode 100644 index 5e1fa747e..000000000 --- a/tools/relocation_packer/test_data/elf_file_unittest_relocs.cc +++ /dev/null @@ -1,1014 +0,0 @@ -// 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. - -// Test data for packing/unpacking. When compiled, creates a run of -// relative relocations. -// -// See generate_elf_file_unittest_relocs.sh for instructions on how to build -// unit test data from this source file. - -const int i = 0; - -// Generator: -// python -c 'for i in xrange(0,1000):print"const void* pointer_%d = &i;"%i' -const void* pointer_0 = &i; -const void* pointer_1 = &i; -const void* pointer_2 = &i; -const void* pointer_3 = &i; -const void* pointer_4 = &i; -const void* pointer_5 = &i; -const void* pointer_6 = &i; -const void* pointer_7 = &i; -const void* pointer_8 = &i; -const void* pointer_9 = &i; -const void* pointer_10 = &i; -const void* pointer_11 = &i; -const void* pointer_12 = &i; -const void* pointer_13 = &i; -const void* pointer_14 = &i; -const void* pointer_15 = &i; -const void* pointer_16 = &i; -const void* pointer_17 = &i; -const void* pointer_18 = &i; -const void* pointer_19 = &i; -const void* pointer_20 = &i; -const void* pointer_21 = &i; -const void* pointer_22 = &i; -const void* pointer_23 = &i; -const void* pointer_24 = &i; -const void* pointer_25 = &i; -const void* pointer_26 = &i; -const void* pointer_27 = &i; -const void* pointer_28 = &i; -const void* pointer_29 = &i; -const void* pointer_30 = &i; -const void* pointer_31 = &i; -const void* pointer_32 = &i; -const void* pointer_33 = &i; -const void* pointer_34 = &i; -const void* pointer_35 = &i; -const void* pointer_36 = &i; -const void* pointer_37 = &i; -const void* pointer_38 = &i; -const void* pointer_39 = &i; -const void* pointer_40 = &i; -const void* pointer_41 = &i; -const void* pointer_42 = &i; -const void* pointer_43 = &i; -const void* pointer_44 = &i; -const void* pointer_45 = &i; -const void* pointer_46 = &i; -const void* pointer_47 = &i; -const void* pointer_48 = &i; -const void* pointer_49 = &i; -const void* pointer_50 = &i; -const void* pointer_51 = &i; -const void* pointer_52 = &i; -const void* pointer_53 = &i; -const void* pointer_54 = &i; -const void* pointer_55 = &i; -const void* pointer_56 = &i; -const void* pointer_57 = &i; -const void* pointer_58 = &i; -const void* pointer_59 = &i; -const void* pointer_60 = &i; -const void* pointer_61 = &i; -const void* pointer_62 = &i; -const void* pointer_63 = &i; -const void* pointer_64 = &i; -const void* pointer_65 = &i; -const void* pointer_66 = &i; -const void* pointer_67 = &i; -const void* pointer_68 = &i; -const void* pointer_69 = &i; -const void* pointer_70 = &i; -const void* pointer_71 = &i; -const void* pointer_72 = &i; -const void* pointer_73 = &i; -const void* pointer_74 = &i; -const void* pointer_75 = &i; -const void* pointer_76 = &i; -const void* pointer_77 = &i; -const void* pointer_78 = &i; -const void* pointer_79 = &i; -const void* pointer_80 = &i; -const void* pointer_81 = &i; -const void* pointer_82 = &i; -const void* pointer_83 = &i; -const void* pointer_84 = &i; -const void* pointer_85 = &i; -const void* pointer_86 = &i; -const void* pointer_87 = &i; -const void* pointer_88 = &i; -const void* pointer_89 = &i; -const void* pointer_90 = &i; -const void* pointer_91 = &i; -const void* pointer_92 = &i; -const void* pointer_93 = &i; -const void* pointer_94 = &i; -const void* pointer_95 = &i; -const void* pointer_96 = &i; -const void* pointer_97 = &i; -const void* pointer_98 = &i; -const void* pointer_99 = &i; -const void* pointer_100 = &i; -const void* pointer_101 = &i; -const void* pointer_102 = &i; -const void* pointer_103 = &i; -const void* pointer_104 = &i; -const void* pointer_105 = &i; -const void* pointer_106 = &i; -const void* pointer_107 = &i; -const void* pointer_108 = &i; -const void* pointer_109 = &i; -const void* pointer_110 = &i; -const void* pointer_111 = &i; -const void* pointer_112 = &i; -const void* pointer_113 = &i; -const void* pointer_114 = &i; -const void* pointer_115 = &i; -const void* pointer_116 = &i; -const void* pointer_117 = &i; -const void* pointer_118 = &i; -const void* pointer_119 = &i; -const void* pointer_120 = &i; -const void* pointer_121 = &i; -const void* pointer_122 = &i; -const void* pointer_123 = &i; -const void* pointer_124 = &i; -const void* pointer_125 = &i; -const void* pointer_126 = &i; -const void* pointer_127 = &i; -const void* pointer_128 = &i; -const void* pointer_129 = &i; -const void* pointer_130 = &i; -const void* pointer_131 = &i; -const void* pointer_132 = &i; -const void* pointer_133 = &i; -const void* pointer_134 = &i; -const void* pointer_135 = &i; -const void* pointer_136 = &i; -const void* pointer_137 = &i; -const void* pointer_138 = &i; -const void* pointer_139 = &i; -const void* pointer_140 = &i; -const void* pointer_141 = &i; -const void* pointer_142 = &i; -const void* pointer_143 = &i; -const void* pointer_144 = &i; -const void* pointer_145 = &i; -const void* pointer_146 = &i; -const void* pointer_147 = &i; -const void* pointer_148 = &i; -const void* pointer_149 = &i; -const void* pointer_150 = &i; -const void* pointer_151 = &i; -const void* pointer_152 = &i; -const void* pointer_153 = &i; -const void* pointer_154 = &i; -const void* pointer_155 = &i; -const void* pointer_156 = &i; -const void* pointer_157 = &i; -const void* pointer_158 = &i; -const void* pointer_159 = &i; -const void* pointer_160 = &i; -const void* pointer_161 = &i; -const void* pointer_162 = &i; -const void* pointer_163 = &i; -const void* pointer_164 = &i; -const void* pointer_165 = &i; -const void* pointer_166 = &i; -const void* pointer_167 = &i; -const void* pointer_168 = &i; -const void* pointer_169 = &i; -const void* pointer_170 = &i; -const void* pointer_171 = &i; -const void* pointer_172 = &i; -const void* pointer_173 = &i; -const void* pointer_174 = &i; -const void* pointer_175 = &i; -const void* pointer_176 = &i; -const void* pointer_177 = &i; -const void* pointer_178 = &i; -const void* pointer_179 = &i; -const void* pointer_180 = &i; -const void* pointer_181 = &i; -const void* pointer_182 = &i; -const void* pointer_183 = &i; -const void* pointer_184 = &i; -const void* pointer_185 = &i; -const void* pointer_186 = &i; -const void* pointer_187 = &i; -const void* pointer_188 = &i; -const void* pointer_189 = &i; -const void* pointer_190 = &i; -const void* pointer_191 = &i; -const void* pointer_192 = &i; -const void* pointer_193 = &i; -const void* pointer_194 = &i; -const void* pointer_195 = &i; -const void* pointer_196 = &i; -const void* pointer_197 = &i; -const void* pointer_198 = &i; -const void* pointer_199 = &i; -const void* pointer_200 = &i; -const void* pointer_201 = &i; -const void* pointer_202 = &i; -const void* pointer_203 = &i; -const void* pointer_204 = &i; -const void* pointer_205 = &i; -const void* pointer_206 = &i; -const void* pointer_207 = &i; -const void* pointer_208 = &i; -const void* pointer_209 = &i; -const void* pointer_210 = &i; -const void* pointer_211 = &i; -const void* pointer_212 = &i; -const void* pointer_213 = &i; -const void* pointer_214 = &i; -const void* pointer_215 = &i; -const void* pointer_216 = &i; -const void* pointer_217 = &i; -const void* pointer_218 = &i; -const void* pointer_219 = &i; -const void* pointer_220 = &i; -const void* pointer_221 = &i; -const void* pointer_222 = &i; -const void* pointer_223 = &i; -const void* pointer_224 = &i; -const void* pointer_225 = &i; -const void* pointer_226 = &i; -const void* pointer_227 = &i; -const void* pointer_228 = &i; -const void* pointer_229 = &i; -const void* pointer_230 = &i; -const void* pointer_231 = &i; -const void* pointer_232 = &i; -const void* pointer_233 = &i; -const void* pointer_234 = &i; -const void* pointer_235 = &i; -const void* pointer_236 = &i; -const void* pointer_237 = &i; -const void* pointer_238 = &i; -const void* pointer_239 = &i; -const void* pointer_240 = &i; -const void* pointer_241 = &i; -const void* pointer_242 = &i; -const void* pointer_243 = &i; -const void* pointer_244 = &i; -const void* pointer_245 = &i; -const void* pointer_246 = &i; -const void* pointer_247 = &i; -const void* pointer_248 = &i; -const void* pointer_249 = &i; -const void* pointer_250 = &i; -const void* pointer_251 = &i; -const void* pointer_252 = &i; -const void* pointer_253 = &i; -const void* pointer_254 = &i; -const void* pointer_255 = &i; -const void* pointer_256 = &i; -const void* pointer_257 = &i; -const void* pointer_258 = &i; -const void* pointer_259 = &i; -const void* pointer_260 = &i; -const void* pointer_261 = &i; -const void* pointer_262 = &i; -const void* pointer_263 = &i; -const void* pointer_264 = &i; -const void* pointer_265 = &i; -const void* pointer_266 = &i; -const void* pointer_267 = &i; -const void* pointer_268 = &i; -const void* pointer_269 = &i; -const void* pointer_270 = &i; -const void* pointer_271 = &i; -const void* pointer_272 = &i; -const void* pointer_273 = &i; -const void* pointer_274 = &i; -const void* pointer_275 = &i; -const void* pointer_276 = &i; -const void* pointer_277 = &i; -const void* pointer_278 = &i; -const void* pointer_279 = &i; -const void* pointer_280 = &i; -const void* pointer_281 = &i; -const void* pointer_282 = &i; -const void* pointer_283 = &i; -const void* pointer_284 = &i; -const void* pointer_285 = &i; -const void* pointer_286 = &i; -const void* pointer_287 = &i; -const void* pointer_288 = &i; -const void* pointer_289 = &i; -const void* pointer_290 = &i; -const void* pointer_291 = &i; -const void* pointer_292 = &i; -const void* pointer_293 = &i; -const void* pointer_294 = &i; -const void* pointer_295 = &i; -const void* pointer_296 = &i; -const void* pointer_297 = &i; -const void* pointer_298 = &i; -const void* pointer_299 = &i; -const void* pointer_300 = &i; -const void* pointer_301 = &i; -const void* pointer_302 = &i; -const void* pointer_303 = &i; -const void* pointer_304 = &i; -const void* pointer_305 = &i; -const void* pointer_306 = &i; -const void* pointer_307 = &i; -const void* pointer_308 = &i; -const void* pointer_309 = &i; -const void* pointer_310 = &i; -const void* pointer_311 = &i; -const void* pointer_312 = &i; -const void* pointer_313 = &i; -const void* pointer_314 = &i; -const void* pointer_315 = &i; -const void* pointer_316 = &i; -const void* pointer_317 = &i; -const void* pointer_318 = &i; -const void* pointer_319 = &i; -const void* pointer_320 = &i; -const void* pointer_321 = &i; -const void* pointer_322 = &i; -const void* pointer_323 = &i; -const void* pointer_324 = &i; -const void* pointer_325 = &i; -const void* pointer_326 = &i; -const void* pointer_327 = &i; -const void* pointer_328 = &i; -const void* pointer_329 = &i; -const void* pointer_330 = &i; -const void* pointer_331 = &i; -const void* pointer_332 = &i; -const void* pointer_333 = &i; -const void* pointer_334 = &i; -const void* pointer_335 = &i; -const void* pointer_336 = &i; -const void* pointer_337 = &i; -const void* pointer_338 = &i; -const void* pointer_339 = &i; -const void* pointer_340 = &i; -const void* pointer_341 = &i; -const void* pointer_342 = &i; -const void* pointer_343 = &i; -const void* pointer_344 = &i; -const void* pointer_345 = &i; -const void* pointer_346 = &i; -const void* pointer_347 = &i; -const void* pointer_348 = &i; -const void* pointer_349 = &i; -const void* pointer_350 = &i; -const void* pointer_351 = &i; -const void* pointer_352 = &i; -const void* pointer_353 = &i; -const void* pointer_354 = &i; -const void* pointer_355 = &i; -const void* pointer_356 = &i; -const void* pointer_357 = &i; -const void* pointer_358 = &i; -const void* pointer_359 = &i; -const void* pointer_360 = &i; -const void* pointer_361 = &i; -const void* pointer_362 = &i; -const void* pointer_363 = &i; -const void* pointer_364 = &i; -const void* pointer_365 = &i; -const void* pointer_366 = &i; -const void* pointer_367 = &i; -const void* pointer_368 = &i; -const void* pointer_369 = &i; -const void* pointer_370 = &i; -const void* pointer_371 = &i; -const void* pointer_372 = &i; -const void* pointer_373 = &i; -const void* pointer_374 = &i; -const void* pointer_375 = &i; -const void* pointer_376 = &i; -const void* pointer_377 = &i; -const void* pointer_378 = &i; -const void* pointer_379 = &i; -const void* pointer_380 = &i; -const void* pointer_381 = &i; -const void* pointer_382 = &i; -const void* pointer_383 = &i; -const void* pointer_384 = &i; -const void* pointer_385 = &i; -const void* pointer_386 = &i; -const void* pointer_387 = &i; -const void* pointer_388 = &i; -const void* pointer_389 = &i; -const void* pointer_390 = &i; -const void* pointer_391 = &i; -const void* pointer_392 = &i; -const void* pointer_393 = &i; -const void* pointer_394 = &i; -const void* pointer_395 = &i; -const void* pointer_396 = &i; -const void* pointer_397 = &i; -const void* pointer_398 = &i; -const void* pointer_399 = &i; -const void* pointer_400 = &i; -const void* pointer_401 = &i; -const void* pointer_402 = &i; -const void* pointer_403 = &i; -const void* pointer_404 = &i; -const void* pointer_405 = &i; -const void* pointer_406 = &i; -const void* pointer_407 = &i; -const void* pointer_408 = &i; -const void* pointer_409 = &i; -const void* pointer_410 = &i; -const void* pointer_411 = &i; -const void* pointer_412 = &i; -const void* pointer_413 = &i; -const void* pointer_414 = &i; -const void* pointer_415 = &i; -const void* pointer_416 = &i; -const void* pointer_417 = &i; -const void* pointer_418 = &i; -const void* pointer_419 = &i; -const void* pointer_420 = &i; -const void* pointer_421 = &i; -const void* pointer_422 = &i; -const void* pointer_423 = &i; -const void* pointer_424 = &i; -const void* pointer_425 = &i; -const void* pointer_426 = &i; -const void* pointer_427 = &i; -const void* pointer_428 = &i; -const void* pointer_429 = &i; -const void* pointer_430 = &i; -const void* pointer_431 = &i; -const void* pointer_432 = &i; -const void* pointer_433 = &i; -const void* pointer_434 = &i; -const void* pointer_435 = &i; -const void* pointer_436 = &i; -const void* pointer_437 = &i; -const void* pointer_438 = &i; -const void* pointer_439 = &i; -const void* pointer_440 = &i; -const void* pointer_441 = &i; -const void* pointer_442 = &i; -const void* pointer_443 = &i; -const void* pointer_444 = &i; -const void* pointer_445 = &i; -const void* pointer_446 = &i; -const void* pointer_447 = &i; -const void* pointer_448 = &i; -const void* pointer_449 = &i; -const void* pointer_450 = &i; -const void* pointer_451 = &i; -const void* pointer_452 = &i; -const void* pointer_453 = &i; -const void* pointer_454 = &i; -const void* pointer_455 = &i; -const void* pointer_456 = &i; -const void* pointer_457 = &i; -const void* pointer_458 = &i; -const void* pointer_459 = &i; -const void* pointer_460 = &i; -const void* pointer_461 = &i; -const void* pointer_462 = &i; -const void* pointer_463 = &i; -const void* pointer_464 = &i; -const void* pointer_465 = &i; -const void* pointer_466 = &i; -const void* pointer_467 = &i; -const void* pointer_468 = &i; -const void* pointer_469 = &i; -const void* pointer_470 = &i; -const void* pointer_471 = &i; -const void* pointer_472 = &i; -const void* pointer_473 = &i; -const void* pointer_474 = &i; -const void* pointer_475 = &i; -const void* pointer_476 = &i; -const void* pointer_477 = &i; -const void* pointer_478 = &i; -const void* pointer_479 = &i; -const void* pointer_480 = &i; -const void* pointer_481 = &i; -const void* pointer_482 = &i; -const void* pointer_483 = &i; -const void* pointer_484 = &i; -const void* pointer_485 = &i; -const void* pointer_486 = &i; -const void* pointer_487 = &i; -const void* pointer_488 = &i; -const void* pointer_489 = &i; -const void* pointer_490 = &i; -const void* pointer_491 = &i; -const void* pointer_492 = &i; -const void* pointer_493 = &i; -const void* pointer_494 = &i; -const void* pointer_495 = &i; -const void* pointer_496 = &i; -const void* pointer_497 = &i; -const void* pointer_498 = &i; -const void* pointer_499 = &i; -const void* pointer_500 = &i; -const void* pointer_501 = &i; -const void* pointer_502 = &i; -const void* pointer_503 = &i; -const void* pointer_504 = &i; -const void* pointer_505 = &i; -const void* pointer_506 = &i; -const void* pointer_507 = &i; -const void* pointer_508 = &i; -const void* pointer_509 = &i; -const void* pointer_510 = &i; -const void* pointer_511 = &i; -const void* pointer_512 = &i; -const void* pointer_513 = &i; -const void* pointer_514 = &i; -const void* pointer_515 = &i; -const void* pointer_516 = &i; -const void* pointer_517 = &i; -const void* pointer_518 = &i; -const void* pointer_519 = &i; -const void* pointer_520 = &i; -const void* pointer_521 = &i; -const void* pointer_522 = &i; -const void* pointer_523 = &i; -const void* pointer_524 = &i; -const void* pointer_525 = &i; -const void* pointer_526 = &i; -const void* pointer_527 = &i; -const void* pointer_528 = &i; -const void* pointer_529 = &i; -const void* pointer_530 = &i; -const void* pointer_531 = &i; -const void* pointer_532 = &i; -const void* pointer_533 = &i; -const void* pointer_534 = &i; -const void* pointer_535 = &i; -const void* pointer_536 = &i; -const void* pointer_537 = &i; -const void* pointer_538 = &i; -const void* pointer_539 = &i; -const void* pointer_540 = &i; -const void* pointer_541 = &i; -const void* pointer_542 = &i; -const void* pointer_543 = &i; -const void* pointer_544 = &i; -const void* pointer_545 = &i; -const void* pointer_546 = &i; -const void* pointer_547 = &i; -const void* pointer_548 = &i; -const void* pointer_549 = &i; -const void* pointer_550 = &i; -const void* pointer_551 = &i; -const void* pointer_552 = &i; -const void* pointer_553 = &i; -const void* pointer_554 = &i; -const void* pointer_555 = &i; -const void* pointer_556 = &i; -const void* pointer_557 = &i; -const void* pointer_558 = &i; -const void* pointer_559 = &i; -const void* pointer_560 = &i; -const void* pointer_561 = &i; -const void* pointer_562 = &i; -const void* pointer_563 = &i; -const void* pointer_564 = &i; -const void* pointer_565 = &i; -const void* pointer_566 = &i; -const void* pointer_567 = &i; -const void* pointer_568 = &i; -const void* pointer_569 = &i; -const void* pointer_570 = &i; -const void* pointer_571 = &i; -const void* pointer_572 = &i; -const void* pointer_573 = &i; -const void* pointer_574 = &i; -const void* pointer_575 = &i; -const void* pointer_576 = &i; -const void* pointer_577 = &i; -const void* pointer_578 = &i; -const void* pointer_579 = &i; -const void* pointer_580 = &i; -const void* pointer_581 = &i; -const void* pointer_582 = &i; -const void* pointer_583 = &i; -const void* pointer_584 = &i; -const void* pointer_585 = &i; -const void* pointer_586 = &i; -const void* pointer_587 = &i; -const void* pointer_588 = &i; -const void* pointer_589 = &i; -const void* pointer_590 = &i; -const void* pointer_591 = &i; -const void* pointer_592 = &i; -const void* pointer_593 = &i; -const void* pointer_594 = &i; -const void* pointer_595 = &i; -const void* pointer_596 = &i; -const void* pointer_597 = &i; -const void* pointer_598 = &i; -const void* pointer_599 = &i; -const void* pointer_600 = &i; -const void* pointer_601 = &i; -const void* pointer_602 = &i; -const void* pointer_603 = &i; -const void* pointer_604 = &i; -const void* pointer_605 = &i; -const void* pointer_606 = &i; -const void* pointer_607 = &i; -const void* pointer_608 = &i; -const void* pointer_609 = &i; -const void* pointer_610 = &i; -const void* pointer_611 = &i; -const void* pointer_612 = &i; -const void* pointer_613 = &i; -const void* pointer_614 = &i; -const void* pointer_615 = &i; -const void* pointer_616 = &i; -const void* pointer_617 = &i; -const void* pointer_618 = &i; -const void* pointer_619 = &i; -const void* pointer_620 = &i; -const void* pointer_621 = &i; -const void* pointer_622 = &i; -const void* pointer_623 = &i; -const void* pointer_624 = &i; -const void* pointer_625 = &i; -const void* pointer_626 = &i; -const void* pointer_627 = &i; -const void* pointer_628 = &i; -const void* pointer_629 = &i; -const void* pointer_630 = &i; -const void* pointer_631 = &i; -const void* pointer_632 = &i; -const void* pointer_633 = &i; -const void* pointer_634 = &i; -const void* pointer_635 = &i; -const void* pointer_636 = &i; -const void* pointer_637 = &i; -const void* pointer_638 = &i; -const void* pointer_639 = &i; -const void* pointer_640 = &i; -const void* pointer_641 = &i; -const void* pointer_642 = &i; -const void* pointer_643 = &i; -const void* pointer_644 = &i; -const void* pointer_645 = &i; -const void* pointer_646 = &i; -const void* pointer_647 = &i; -const void* pointer_648 = &i; -const void* pointer_649 = &i; -const void* pointer_650 = &i; -const void* pointer_651 = &i; -const void* pointer_652 = &i; -const void* pointer_653 = &i; -const void* pointer_654 = &i; -const void* pointer_655 = &i; -const void* pointer_656 = &i; -const void* pointer_657 = &i; -const void* pointer_658 = &i; -const void* pointer_659 = &i; -const void* pointer_660 = &i; -const void* pointer_661 = &i; -const void* pointer_662 = &i; -const void* pointer_663 = &i; -const void* pointer_664 = &i; -const void* pointer_665 = &i; -const void* pointer_666 = &i; -const void* pointer_667 = &i; -const void* pointer_668 = &i; -const void* pointer_669 = &i; -const void* pointer_670 = &i; -const void* pointer_671 = &i; -const void* pointer_672 = &i; -const void* pointer_673 = &i; -const void* pointer_674 = &i; -const void* pointer_675 = &i; -const void* pointer_676 = &i; -const void* pointer_677 = &i; -const void* pointer_678 = &i; -const void* pointer_679 = &i; -const void* pointer_680 = &i; -const void* pointer_681 = &i; -const void* pointer_682 = &i; -const void* pointer_683 = &i; -const void* pointer_684 = &i; -const void* pointer_685 = &i; -const void* pointer_686 = &i; -const void* pointer_687 = &i; -const void* pointer_688 = &i; -const void* pointer_689 = &i; -const void* pointer_690 = &i; -const void* pointer_691 = &i; -const void* pointer_692 = &i; -const void* pointer_693 = &i; -const void* pointer_694 = &i; -const void* pointer_695 = &i; -const void* pointer_696 = &i; -const void* pointer_697 = &i; -const void* pointer_698 = &i; -const void* pointer_699 = &i; -const void* pointer_700 = &i; -const void* pointer_701 = &i; -const void* pointer_702 = &i; -const void* pointer_703 = &i; -const void* pointer_704 = &i; -const void* pointer_705 = &i; -const void* pointer_706 = &i; -const void* pointer_707 = &i; -const void* pointer_708 = &i; -const void* pointer_709 = &i; -const void* pointer_710 = &i; -const void* pointer_711 = &i; -const void* pointer_712 = &i; -const void* pointer_713 = &i; -const void* pointer_714 = &i; -const void* pointer_715 = &i; -const void* pointer_716 = &i; -const void* pointer_717 = &i; -const void* pointer_718 = &i; -const void* pointer_719 = &i; -const void* pointer_720 = &i; -const void* pointer_721 = &i; -const void* pointer_722 = &i; -const void* pointer_723 = &i; -const void* pointer_724 = &i; -const void* pointer_725 = &i; -const void* pointer_726 = &i; -const void* pointer_727 = &i; -const void* pointer_728 = &i; -const void* pointer_729 = &i; -const void* pointer_730 = &i; -const void* pointer_731 = &i; -const void* pointer_732 = &i; -const void* pointer_733 = &i; -const void* pointer_734 = &i; -const void* pointer_735 = &i; -const void* pointer_736 = &i; -const void* pointer_737 = &i; -const void* pointer_738 = &i; -const void* pointer_739 = &i; -const void* pointer_740 = &i; -const void* pointer_741 = &i; -const void* pointer_742 = &i; -const void* pointer_743 = &i; -const void* pointer_744 = &i; -const void* pointer_745 = &i; -const void* pointer_746 = &i; -const void* pointer_747 = &i; -const void* pointer_748 = &i; -const void* pointer_749 = &i; -const void* pointer_750 = &i; -const void* pointer_751 = &i; -const void* pointer_752 = &i; -const void* pointer_753 = &i; -const void* pointer_754 = &i; -const void* pointer_755 = &i; -const void* pointer_756 = &i; -const void* pointer_757 = &i; -const void* pointer_758 = &i; -const void* pointer_759 = &i; -const void* pointer_760 = &i; -const void* pointer_761 = &i; -const void* pointer_762 = &i; -const void* pointer_763 = &i; -const void* pointer_764 = &i; -const void* pointer_765 = &i; -const void* pointer_766 = &i; -const void* pointer_767 = &i; -const void* pointer_768 = &i; -const void* pointer_769 = &i; -const void* pointer_770 = &i; -const void* pointer_771 = &i; -const void* pointer_772 = &i; -const void* pointer_773 = &i; -const void* pointer_774 = &i; -const void* pointer_775 = &i; -const void* pointer_776 = &i; -const void* pointer_777 = &i; -const void* pointer_778 = &i; -const void* pointer_779 = &i; -const void* pointer_780 = &i; -const void* pointer_781 = &i; -const void* pointer_782 = &i; -const void* pointer_783 = &i; -const void* pointer_784 = &i; -const void* pointer_785 = &i; -const void* pointer_786 = &i; -const void* pointer_787 = &i; -const void* pointer_788 = &i; -const void* pointer_789 = &i; -const void* pointer_790 = &i; -const void* pointer_791 = &i; -const void* pointer_792 = &i; -const void* pointer_793 = &i; -const void* pointer_794 = &i; -const void* pointer_795 = &i; -const void* pointer_796 = &i; -const void* pointer_797 = &i; -const void* pointer_798 = &i; -const void* pointer_799 = &i; -const void* pointer_800 = &i; -const void* pointer_801 = &i; -const void* pointer_802 = &i; -const void* pointer_803 = &i; -const void* pointer_804 = &i; -const void* pointer_805 = &i; -const void* pointer_806 = &i; -const void* pointer_807 = &i; -const void* pointer_808 = &i; -const void* pointer_809 = &i; -const void* pointer_810 = &i; -const void* pointer_811 = &i; -const void* pointer_812 = &i; -const void* pointer_813 = &i; -const void* pointer_814 = &i; -const void* pointer_815 = &i; -const void* pointer_816 = &i; -const void* pointer_817 = &i; -const void* pointer_818 = &i; -const void* pointer_819 = &i; -const void* pointer_820 = &i; -const void* pointer_821 = &i; -const void* pointer_822 = &i; -const void* pointer_823 = &i; -const void* pointer_824 = &i; -const void* pointer_825 = &i; -const void* pointer_826 = &i; -const void* pointer_827 = &i; -const void* pointer_828 = &i; -const void* pointer_829 = &i; -const void* pointer_830 = &i; -const void* pointer_831 = &i; -const void* pointer_832 = &i; -const void* pointer_833 = &i; -const void* pointer_834 = &i; -const void* pointer_835 = &i; -const void* pointer_836 = &i; -const void* pointer_837 = &i; -const void* pointer_838 = &i; -const void* pointer_839 = &i; -const void* pointer_840 = &i; -const void* pointer_841 = &i; -const void* pointer_842 = &i; -const void* pointer_843 = &i; -const void* pointer_844 = &i; -const void* pointer_845 = &i; -const void* pointer_846 = &i; -const void* pointer_847 = &i; -const void* pointer_848 = &i; -const void* pointer_849 = &i; -const void* pointer_850 = &i; -const void* pointer_851 = &i; -const void* pointer_852 = &i; -const void* pointer_853 = &i; -const void* pointer_854 = &i; -const void* pointer_855 = &i; -const void* pointer_856 = &i; -const void* pointer_857 = &i; -const void* pointer_858 = &i; -const void* pointer_859 = &i; -const void* pointer_860 = &i; -const void* pointer_861 = &i; -const void* pointer_862 = &i; -const void* pointer_863 = &i; -const void* pointer_864 = &i; -const void* pointer_865 = &i; -const void* pointer_866 = &i; -const void* pointer_867 = &i; -const void* pointer_868 = &i; -const void* pointer_869 = &i; -const void* pointer_870 = &i; -const void* pointer_871 = &i; -const void* pointer_872 = &i; -const void* pointer_873 = &i; -const void* pointer_874 = &i; -const void* pointer_875 = &i; -const void* pointer_876 = &i; -const void* pointer_877 = &i; -const void* pointer_878 = &i; -const void* pointer_879 = &i; -const void* pointer_880 = &i; -const void* pointer_881 = &i; -const void* pointer_882 = &i; -const void* pointer_883 = &i; -const void* pointer_884 = &i; -const void* pointer_885 = &i; -const void* pointer_886 = &i; -const void* pointer_887 = &i; -const void* pointer_888 = &i; -const void* pointer_889 = &i; -const void* pointer_890 = &i; -const void* pointer_891 = &i; -const void* pointer_892 = &i; -const void* pointer_893 = &i; -const void* pointer_894 = &i; -const void* pointer_895 = &i; -const void* pointer_896 = &i; -const void* pointer_897 = &i; -const void* pointer_898 = &i; -const void* pointer_899 = &i; -const void* pointer_900 = &i; -const void* pointer_901 = &i; -const void* pointer_902 = &i; -const void* pointer_903 = &i; -const void* pointer_904 = &i; -const void* pointer_905 = &i; -const void* pointer_906 = &i; -const void* pointer_907 = &i; -const void* pointer_908 = &i; -const void* pointer_909 = &i; -const void* pointer_910 = &i; -const void* pointer_911 = &i; -const void* pointer_912 = &i; -const void* pointer_913 = &i; -const void* pointer_914 = &i; -const void* pointer_915 = &i; -const void* pointer_916 = &i; -const void* pointer_917 = &i; -const void* pointer_918 = &i; -const void* pointer_919 = &i; -const void* pointer_920 = &i; -const void* pointer_921 = &i; -const void* pointer_922 = &i; -const void* pointer_923 = &i; -const void* pointer_924 = &i; -const void* pointer_925 = &i; -const void* pointer_926 = &i; -const void* pointer_927 = &i; -const void* pointer_928 = &i; -const void* pointer_929 = &i; -const void* pointer_930 = &i; -const void* pointer_931 = &i; -const void* pointer_932 = &i; -const void* pointer_933 = &i; -const void* pointer_934 = &i; -const void* pointer_935 = &i; -const void* pointer_936 = &i; -const void* pointer_937 = &i; -const void* pointer_938 = &i; -const void* pointer_939 = &i; -const void* pointer_940 = &i; -const void* pointer_941 = &i; -const void* pointer_942 = &i; -const void* pointer_943 = &i; -const void* pointer_944 = &i; -const void* pointer_945 = &i; -const void* pointer_946 = &i; -const void* pointer_947 = &i; -const void* pointer_948 = &i; -const void* pointer_949 = &i; -const void* pointer_950 = &i; -const void* pointer_951 = &i; -const void* pointer_952 = &i; -const void* pointer_953 = &i; -const void* pointer_954 = &i; -const void* pointer_955 = &i; -const void* pointer_956 = &i; -const void* pointer_957 = &i; -const void* pointer_958 = &i; -const void* pointer_959 = &i; -const void* pointer_960 = &i; -const void* pointer_961 = &i; -const void* pointer_962 = &i; -const void* pointer_963 = &i; -const void* pointer_964 = &i; -const void* pointer_965 = &i; -const void* pointer_966 = &i; -const void* pointer_967 = &i; -const void* pointer_968 = &i; -const void* pointer_969 = &i; -const void* pointer_970 = &i; -const void* pointer_971 = &i; -const void* pointer_972 = &i; -const void* pointer_973 = &i; -const void* pointer_974 = &i; -const void* pointer_975 = &i; -const void* pointer_976 = &i; -const void* pointer_977 = &i; -const void* pointer_978 = &i; -const void* pointer_979 = &i; -const void* pointer_980 = &i; -const void* pointer_981 = &i; -const void* pointer_982 = &i; -const void* pointer_983 = &i; -const void* pointer_984 = &i; -const void* pointer_985 = &i; -const void* pointer_986 = &i; -const void* pointer_987 = &i; -const void* pointer_988 = &i; -const void* pointer_989 = &i; -const void* pointer_990 = &i; -const void* pointer_991 = &i; -const void* pointer_992 = &i; -const void* pointer_993 = &i; -const void* pointer_994 = &i; -const void* pointer_995 = &i; -const void* pointer_996 = &i; -const void* pointer_997 = &i; -const void* pointer_998 = &i; -const void* pointer_999 = &i; diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so deleted file mode 100755 index 5e339ae4b..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so deleted file mode 100755 index 253dd97c1..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm32_packed.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so deleted file mode 100755 index d3d0194da..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so deleted file mode 100755 index 269b97554..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so deleted file mode 100755 index 42db62c24..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so deleted file mode 100755 index 27817cc38..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so deleted file mode 100755 index 6da324bb7..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so deleted file mode 100755 index b11ca4883..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so deleted file mode 100755 index 6cb689ec5..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so and /dev/null differ diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so deleted file mode 100755 index 60b9ad179..000000000 Binary files a/tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so and /dev/null differ -- cgit v1.2.3