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 |
index 3778e0105c5991a32d827acd58d1465a9a9a6288..cdc4e47d5105f9397e99162bb5fa867324c1ad59 100644 |
--- a/tools/relocation_packer/src/elf_file.h |
+++ b/tools/relocation_packer/src/elf_file.h |
@@ -4,18 +4,24 @@ |
// ELF shared object file updates handler. |
// |
-// Provides functions to remove 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. |
+// Provides functions to remove relative relocations from the .rel.dyn |
+// or .rela.dyn sections and pack into .android.rel.dyn or .android.rela.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: |
+// or android.rela.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 |
+// if file libchrome.<version>.so | grep -q 'ELF 32'; then |
+// arm-linux-androideabi-objcopy |
+// --add-section .android.rel.dyn=/tmp/small |
+// libchrome.<version>.so libchrome.<version>.so.packed |
+// else |
+// aarch64-linux-android-objcopy |
+// --add-section .android.rela.dyn=/tmp/small |
+// libchrome.<version>.so libchrome.<version>.so.packed |
+// fi |
// rm /tmp/small |
// |
// To use, open the file and pass the file descriptor to the constructor, |
@@ -31,24 +37,26 @@ |
// status = elf_file.UnpackRelocations(); |
// close(fd); |
// |
-// SetPadding() causes PackRelocations() to pad .rel.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. |
+// 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 has all of its 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. |
+// A packed shared object file has all of its relative relocations |
+// removed from .rel.dyn or .rela.dyn, and replaced as packed data in |
+// .android.rel.dyn or .android.rela.dyn respectively. 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 ARM relative |
-// relocations with the data already in .rel.dyn, and then writing back the |
-// now expanded .rel.dyn section. |
+// expanding the packed data in .android.rel.dyn or .android.rela.dyn, |
+// combining the relative relocations with the data already in .rel.dyn |
+// or .rela.dyn, and then writing back the now expanded section. |
#ifndef TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ |
#define TOOLS_RELOCATION_PACKER_SRC_ELF_FILE_H_ |
#include <string.h> |
+#include <vector> |
#include "elf.h" |
#include "libelf.h" |
@@ -56,25 +64,28 @@ |
namespace relocation_packer { |
-// An ElfFile reads shared objects, and shuttles ARM relative relocations |
-// between .rel.dyn and .android.rel.dyn sections. |
+// An ElfFile reads shared objects, and shuttles relative relocations |
+// between .rel.dyn or .rela.dyn and .android.rel.dyn or .android.rela.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 ARM relative with |
+ // the .rel.dyn or .rela.dyn section, but instead replace relative with |
// NONE-type entries. |
- // |flag| is true to pad .rel.dyn, false to shrink it. |
- inline void SetPadding(bool flag) { is_padding_rel_dyn_ = flag; } |
+ // |flag| is true to pad .rel.dyn or .rela.dyn, false to shrink it. |
+ inline void SetPadding(bool flag) { is_padding_relocations_ = flag; } |
- // Transfer ARM relative relocations from .rel.dyn to a packed |
- // representation in .android.rel.dyn. Returns true on success. |
+ // 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 ARM relative relocations from a packed representation in |
- // .android.rel.dyn to .rel.dyn. Returns true on success. |
+ // 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: |
@@ -83,12 +94,24 @@ class ElfFile { |
// |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. |
+ template <typename Rel> |
+ bool PackTypedRelocations(const std::vector<Rel>& relocations, |
+ Elf_Data* data); |
+ |
+ // Templated unpacker, helper for UnpackRelocations(). Rel type is one of |
+ // ELF::Rel or ELF::Rela. |
+ template <typename Rel> |
+ bool UnpackTypedRelocations(const std::vector<uint8_t>& packed, |
+ Elf_Data* data); |
+ |
// 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_; |
+ // 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_; |
// File descriptor opened on the shared object. |
int fd_; |
@@ -97,9 +120,12 @@ class ElfFile { |
Elf* elf_; |
// Sections that we manipulate, assigned by Load(). |
- Elf_Scn* rel_dyn_section_; |
+ Elf_Scn* relocations_section_; |
Elf_Scn* dynamic_section_; |
- Elf_Scn* android_rel_dyn_section_; |
+ Elf_Scn* android_relocations_section_; |
+ |
+ // Relocation type found, assigned by Load(). |
+ enum { NONE = 0, REL, RELA } relocations_type_; |
}; |
} // namespace relocation_packer |