diff options
Diffstat (limited to 'tools/relocation_packer/src/elf_file.h')
-rw-r--r-- | tools/relocation_packer/src/elf_file.h | 90 |
1 files changed, 58 insertions, 32 deletions
diff --git a/tools/relocation_packer/src/elf_file.h b/tools/relocation_packer/src/elf_file.h index 3778e01..cdc4e47 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 |