| Index: third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
|
| diff --git a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
|
| index 20b25ef829d3a4af30833ef33974e093d55bc9a4..fb74233d2437a25f909a9c5e7b8594f1bb61ff89 100644
|
| --- a/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
|
| +++ b/third_party/android_platform/bionic/tools/relocation_packer/src/elf_file.cc
|
| @@ -190,6 +190,7 @@ bool ElfFile<ELF>::Load() {
|
| // 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) {
|
| @@ -209,6 +210,11 @@ bool ElfFile<ELF>::Load() {
|
| 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) {
|
| @@ -250,6 +256,7 @@ bool ElfFile<ELF>::Load() {
|
| 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;
|
| }
|
|
|
| @@ -439,6 +446,9 @@ void ElfFile<ELF>::AdjustDynamicSectionForHole(Elf_Scn* dynamic_section,
|
| 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);
|
|
|
| @@ -586,7 +596,7 @@ bool ElfFile<ELF>::PackRelocations() {
|
| const typename ELF::Rel* relocations_base = reinterpret_cast<typename ELF::Rel*>(data->d_buf);
|
| ConvertRelArrayToRelaVector(relocations_base,
|
| data->d_size / sizeof(typename ELF::Rel), &relocations);
|
| - LOG(INFO) << "Relocations : REL";
|
| + 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<typename ELF::Rela*>(data->d_buf);
|
| @@ -594,7 +604,7 @@ bool ElfFile<ELF>::PackRelocations() {
|
| relocations_base,
|
| relocations_base + data->d_size / sizeof(relocations[0]));
|
|
|
| - LOG(INFO) << "Relocations : RELA";
|
| + VLOG(1) << "Relocations : RELA";
|
| } else {
|
| NOTREACHED();
|
| }
|
| @@ -607,10 +617,15 @@ template <typename ELF>
|
| bool ElfFile<ELF>::PackTypedRelocations(std::vector<typename ELF::Rela>* relocations) {
|
| typedef typename ELF::Rela Rela;
|
|
|
| + if (has_android_relocations_) {
|
| + LOG(ERROR) << "Relocation table is already packed";
|
| + return false;
|
| + }
|
| +
|
| // If no relocations then we have nothing packable. Perhaps
|
| // the shared object has already been packed?
|
| if (relocations->empty()) {
|
| - LOG(ERROR) << "No relocations found (already packed?)";
|
| + LOG(ERROR) << "No relocations found";
|
| return false;
|
| }
|
|
|
| @@ -618,18 +633,18 @@ bool ElfFile<ELF>::PackTypedRelocations(std::vector<typename ELF::Rela>* relocat
|
| relocations_type_ == RELA ? sizeof(typename ELF::Rela) : sizeof(typename ELF::Rel);
|
| const size_t initial_bytes = relocations->size() * rel_size;
|
|
|
| - LOG(INFO) << "Unpacked : " << initial_bytes << " bytes";
|
| + VLOG(1) << "Unpacked : " << initial_bytes << " bytes";
|
| std::vector<uint8_t> packed;
|
| RelocationPacker<ELF> packer;
|
|
|
| // Pack relocations: dry run to estimate memory savings.
|
| packer.PackRelocations(*relocations, &packed);
|
| const size_t packed_bytes_estimate = packed.size() * sizeof(packed[0]);
|
| - LOG(INFO) << "Packed (no padding): " << packed_bytes_estimate << " bytes";
|
| + VLOG(1) << "Packed (no padding): " << packed_bytes_estimate << " bytes";
|
|
|
| if (packed.empty()) {
|
| LOG(INFO) << "Too few relocations to pack";
|
| - return false;
|
| + return true;
|
| }
|
|
|
| // Pre-calculate the size of the hole we will close up when we rewrite
|
| @@ -646,12 +661,12 @@ bool ElfFile<ELF>::PackTypedRelocations(std::vector<typename ELF::Rela>* relocat
|
| // Adjusting for alignment may have removed any packing benefit.
|
| if (hole_size == 0) {
|
| LOG(INFO) << "Too few relocations to pack after alignment";
|
| - return false;
|
| + return true;
|
| }
|
|
|
| if (hole_size <= 0) {
|
| LOG(INFO) << "Packing relocations saves no space";
|
| - return false;
|
| + return true;
|
| }
|
|
|
| size_t data_padding_bytes = is_padding_relocations_ ?
|
| @@ -734,7 +749,7 @@ bool ElfFile<ELF>::UnpackRelocations() {
|
| packed.size() > 3 &&
|
| packed[0] == 'A' &&
|
| packed[1] == 'P' &&
|
| - (packed[2] == 'U' || packed[2] == 'S') &&
|
| + packed[2] == 'S' &&
|
| packed[3] == '2') {
|
| LOG(INFO) << "Relocations : " << (relocations_type_ == REL ? "REL" : "RELA");
|
| } else {
|
|
|