Index: tools/relocation_packer/src/elf_file.h |
diff --git a/tools/relocation_packer/src/elf_file.h b/tools/relocation_packer/src/elf_file.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6f23c328931bb9c8af6ff6fe17dd5efb3abbabd7 |
--- /dev/null |
+++ b/tools/relocation_packer/src/elf_file.h |
@@ -0,0 +1,107 @@ |
+// 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 remove R_ARM_RELATIVE relocations from the .rel.dyn |
+// section and pack them in .android.rel.dyn, and unpack to return the file |
+// to its pre-packed state. |
+// |
+// Files to be packed or unpacked must include an existing .android.rel.dyn |
+// section. A standard libchrome.<version>.so will not contain this section, |
+// so the following can be used to add one: |
+// |
+// echo -n 'NULL' >/tmp/small |
+// arm-linux-gnueabi-objcopy |
+// --add-section .android.rel.dyn=/tmp/small |
+// libchrome.<version>.so libchrome.<version>.so.packed |
+// rm /tmp/small |
+// |
+// To use, open the file and pass the file descriptor to the constructor, |
+// then pack or unpack as desired. Packing or unpacking will flush the file |
+// descriptor on success. Example: |
+// |
+// int fd = open(..., O_RDWR); |
+// ElfFile elf_file(fd); |
+// bool status; |
+// if (is_packing) |
+// status = elf_file.PackRelocations(); |
+// else |
+// status = elf_file.UnpackRelocations(); |
+// close(fd); |
+// |
+// SetPadding() causes PackRelocations() to pad .rel.dyn with R_ARM_NONE |
+// 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 has all of its R_ARM_RELATIVE relocations |
+// removed from .rel.dyn, and replaced as packed data in .android.rel.dyn. |
+// The resulting file is shorter than its non-packed original. |
+// |
+// Unpacking a packed file restores the file to its non-packed state, by |
+// expanding the packed data in android.rel.dyn, combining the R_ARM_RELATIVE |
+// relocations with the data already in .rel.dyn, and then writing back the |
+// now expanded .rel.dyn section. |
+ |
+#ifndef TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ |
+#define TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ |
+ |
+#include <string.h> |
+ |
+#include "elf.h" |
+#include "libelf.h" |
+#include "packer.h" |
+ |
+namespace relocation_packer { |
+ |
+// An ElfFile reads shared objects, and shuttles R_ARM_RELATIVE relocations |
+// between .rel.dyn and .android.rel.dyn sections. |
+class ElfFile { |
+ public: |
+ explicit ElfFile(int fd) { memset(this, 0, sizeof(*this)); fd_ = fd; } |
+ ~ElfFile() {} |
+ |
+ // Set padding mode. When padding, PackRelocations() will not shrink |
+ // the .rel.dyn section, but instead replace R_ARM_RELATIVE with |
+ // R_ARM_NONE entries. |
+ // |flag| is true to pad .rel.dyn, false to shrink it. |
+ inline void SetPadding(bool flag) { is_padding_rel_dyn_ = flag; } |
+ |
+ // Transfer R_ARM_RELATIVE relocations from .rel.dyn to a packed |
+ // representation in .android.rel.dyn. Returns true on success. |
+ bool PackRelocations(); |
+ |
+ // Transfer R_ARM_RELATIVE relocations from a packed representation in |
+ // .android.rel.dyn to .rel.dyn. Returns true on success. |
+ bool UnpackRelocations(); |
+ |
+ private: |
+ // 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(); |
+ |
+ // Write ELF file changes. |
+ void Flush(); |
+ |
+ // If set, pad rather than shrink .rel.dyn. Primarily for debugging, |
+ // allows packing to be checked without affecting load addresses. |
+ bool is_padding_rel_dyn_; |
+ |
+ // File descriptor opened on the shared object. |
+ int fd_; |
+ |
+ // Libelf handle, assigned by Load(). |
+ Elf* elf_; |
+ |
+ // Sections that we manipulate, assigned by Load(). |
+ Elf_Scn* rel_dyn_section_; |
+ Elf_Scn* dynamic_section_; |
+ Elf_Scn* android_rel_dyn_section_; |
+}; |
+ |
+} // namespace relocation_packer |
+ |
+#endif // TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ |