Home | History | Annotate | Download | only in src
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Implementation notes:
      6 //
      7 // We need to remove a piece from the ELF shared library.  However, we also
      8 // want to ensure that code and data loads at the same addresses as before
      9 // packing, so that tools like breakpad can still match up addresses found
     10 // in any crash dumps with data extracted from the pre-packed version of
     11 // the shared library.
     12 //
     13 // Arranging this means that we have to split one of the LOAD segments into
     14 // two.  Unfortunately, the program headers are located at the very start
     15 // of the shared library file, so expanding the program header section
     16 // would cause a lot of consequent changes to files offsets that we don't
     17 // really want to have to handle.
     18 //
     19 // Luckily, though, there is a segment that is always present and always
     20 // unused on Android; the GNU_STACK segment.  What we do is to steal that
     21 // and repurpose it to be one of the split LOAD segments.  We then have to
     22 // sort LOAD segments by offset to keep the crazy linker happy.
     23 //
     24 // All of this takes place in SplitProgramHeadersForHole(), used on packing,
     25 // and is unraveled on unpacking in CoalesceProgramHeadersForHole().  See
     26 // commentary on those functions for an example of this segment stealing
     27 // in action.
     28 
     29 #include "elf_file.h"
     30 
     31 #include <stdlib.h>
     32 #include <sys/types.h>
     33 #include <unistd.h>
     34 #include <algorithm>
     35 #include <string>
     36 #include <vector>
     37 
     38 #include "debug.h"
     39 #include "elf_traits.h"
     40 #include "libelf.h"
     41 #include "packer.h"
     42 
     43 namespace relocation_packer {
     44 
     45 // Stub identifier written to 'null out' packed data, "NULL".
     46 static const uint32_t kStubIdentifier = 0x4c4c554eu;
     47 
     48 // Out-of-band dynamic tags used to indicate the offset and size of the
     49 // android packed relocations section.
     50 static const ELF::Sword DT_ANDROID_REL_OFFSET = DT_LOOS;
     51 static const ELF::Sword DT_ANDROID_REL_SIZE = DT_LOOS + 1;
     52 
     53 // Alignment to preserve, in bytes.  This must be at least as large as the
     54 // largest d_align and sh_addralign values found in the loaded file.
     55 // Out of caution for RELRO page alignment, we preserve to a complete target
     56 // page.  See http://www.airs.com/blog/archives/189.
     57 static const size_t kPreserveAlignment = 4096;
     58 
     59 namespace {
     60 
     61 // Get section data.  Checks that the section has exactly one data entry,
     62 // so that the section size and the data size are the same.  True in
     63 // practice for all sections we resize when packing or unpacking.  Done
     64 // by ensuring that a call to elf_getdata(section, data) returns NULL as
     65 // the next data entry.
     66 Elf_Data* GetSectionData(Elf_Scn* section) {
     67   Elf_Data* data = elf_getdata(section, NULL);
     68   CHECK(data && elf_getdata(section, data) == NULL);
     69   return data;
     70 }
     71 
     72 // Rewrite section data.  Allocates new data and makes it the data element's
     73 // buffer.  Relies on program exit to free allocated data.
     74 void RewriteSectionData(Elf_Data* data,
     75                         const void* section_data,
     76                         size_t size) {
     77   CHECK(size == data->d_size);
     78   uint8_t* area = new uint8_t[size];
     79   memcpy(area, section_data, size);
     80   data->d_buf = area;
     81 }
     82 
     83 // Verbose ELF header logging.
     84 void VerboseLogElfHeader(const ELF::Ehdr* elf_header) {
     85   VLOG(1) << "e_phoff = " << elf_header->e_phoff;
     86   VLOG(1) << "e_shoff = " << elf_header->e_shoff;
     87   VLOG(1) << "e_ehsize = " << elf_header->e_ehsize;
     88   VLOG(1) << "e_phentsize = " << elf_header->e_phentsize;
     89   VLOG(1) << "e_phnum = " << elf_header->e_phnum;
     90   VLOG(1) << "e_shnum = " << elf_header->e_shnum;
     91   VLOG(1) << "e_shstrndx = " << elf_header->e_shstrndx;
     92 }
     93 
     94 // Verbose ELF program header logging.
     95 void VerboseLogProgramHeader(size_t program_header_index,
     96                              const ELF::Phdr* program_header) {
     97   std::string type;
     98   switch (program_header->p_type) {
     99     case PT_NULL: type = "NULL"; break;
    100     case PT_LOAD: type = "LOAD"; break;
    101     case PT_DYNAMIC: type = "DYNAMIC"; break;
    102     case PT_INTERP: type = "INTERP"; break;
    103     case PT_PHDR: type = "PHDR"; break;
    104     case PT_GNU_RELRO: type = "GNU_RELRO"; break;
    105     case PT_GNU_STACK: type = "GNU_STACK"; break;
    106     case PT_ARM_EXIDX: type = "EXIDX"; break;
    107     default: type = "(OTHER)"; break;
    108   }
    109   VLOG(1) << "phdr[" << program_header_index << "] : " << type;
    110   VLOG(1) << "  p_offset = " << program_header->p_offset;
    111   VLOG(1) << "  p_vaddr = " << program_header->p_vaddr;
    112   VLOG(1) << "  p_paddr = " << program_header->p_paddr;
    113   VLOG(1) << "  p_filesz = " << program_header->p_filesz;
    114   VLOG(1) << "  p_memsz = " << program_header->p_memsz;
    115   VLOG(1) << "  p_flags = " << program_header->p_flags;
    116   VLOG(1) << "  p_align = " << program_header->p_align;
    117 }
    118 
    119 // Verbose ELF section header logging.
    120 void VerboseLogSectionHeader(const std::string& section_name,
    121                              const ELF::Shdr* section_header) {
    122   VLOG(1) << "section " << section_name;
    123   VLOG(1) << "  sh_addr = " << section_header->sh_addr;
    124   VLOG(1) << "  sh_offset = " << section_header->sh_offset;
    125   VLOG(1) << "  sh_size = " << section_header->sh_size;
    126   VLOG(1) << "  sh_addralign = " << section_header->sh_addralign;
    127 }
    128 
    129 // Verbose ELF section data logging.
    130 void VerboseLogSectionData(const Elf_Data* data) {
    131   VLOG(1) << "  data";
    132   VLOG(1) << "    d_buf = " << data->d_buf;
    133   VLOG(1) << "    d_off = " << data->d_off;
    134   VLOG(1) << "    d_size = " << data->d_size;
    135   VLOG(1) << "    d_align = " << data->d_align;
    136 }
    137 
    138 }  // namespace
    139 
    140 // Load the complete ELF file into a memory image in libelf, and identify
    141 // the .rel.dyn or .rela.dyn, .dynamic, and .android.rel.dyn or
    142 // .android.rela.dyn sections.  No-op if the ELF file has already been loaded.
    143 bool ElfFile::Load() {
    144   if (elf_)
    145     return true;
    146 
    147   Elf* elf = elf_begin(fd_, ELF_C_RDWR, NULL);
    148   CHECK(elf);
    149 
    150   if (elf_kind(elf) != ELF_K_ELF) {
    151     LOG(ERROR) << "File not in ELF format";
    152     return false;
    153   }
    154 
    155   ELF::Ehdr* elf_header = ELF::getehdr(elf);
    156   if (!elf_header) {
    157     LOG(ERROR) << "Failed to load ELF header: " << elf_errmsg(elf_errno());
    158     return false;
    159   }
    160   if (elf_header->e_machine != ELF::kMachine) {
    161     LOG(ERROR) << "ELF file architecture is not " << ELF::Machine();
    162     return false;
    163   }
    164   if (elf_header->e_type != ET_DYN) {
    165     LOG(ERROR) << "ELF file is not a shared object";
    166     return false;
    167   }
    168 
    169   // Require that our endianness matches that of the target, and that both
    170   // are little-endian.  Safe for all current build/target combinations.
    171   const int endian = elf_header->e_ident[EI_DATA];
    172   CHECK(endian == ELFDATA2LSB);
    173   CHECK(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__);
    174 
    175   // Also require that the file class is as expected.
    176   const int file_class = elf_header->e_ident[EI_CLASS];
    177   CHECK(file_class == ELF::kFileClass);
    178 
    179   VLOG(1) << "endian = " << endian << ", file class = " << file_class;
    180   VerboseLogElfHeader(elf_header);
    181 
    182   const ELF::Phdr* elf_program_header = ELF::getphdr(elf);
    183   CHECK(elf_program_header);
    184 
    185   const ELF::Phdr* dynamic_program_header = NULL;
    186   for (size_t i = 0; i < elf_header->e_phnum; ++i) {
    187     const ELF::Phdr* program_header = &elf_program_header[i];
    188     VerboseLogProgramHeader(i, program_header);
    189 
    190     if (program_header->p_type == PT_DYNAMIC) {
    191       CHECK(dynamic_program_header == NULL);
    192       dynamic_program_header = program_header;
    193     }
    194   }
    195   CHECK(dynamic_program_header != NULL);
    196 
    197   size_t string_index;
    198   elf_getshdrstrndx(elf, &string_index);
    199 
    200   // Notes of the dynamic relocations, packed relocations, and .dynamic
    201   // sections.  Found while iterating sections, and later stored in class
    202   // attributes.
    203   Elf_Scn* found_relocations_section = NULL;
    204   Elf_Scn* found_android_relocations_section = NULL;
    205   Elf_Scn* found_dynamic_section = NULL;
    206 
    207   // Notes of relocation section types seen.  We require one or the other of
    208   // these; both is unsupported.
    209   bool has_rel_relocations = false;
    210   bool has_rela_relocations = false;
    211 
    212   Elf_Scn* section = NULL;
    213   while ((section = elf_nextscn(elf, section)) != NULL) {
    214     const ELF::Shdr* section_header = ELF::getshdr(section);
    215     std::string name = elf_strptr(elf, string_index, section_header->sh_name);
    216     VerboseLogSectionHeader(name, section_header);
    217 
    218     // Note relocation section types.
    219     if (section_header->sh_type == SHT_REL) {
    220       has_rel_relocations = true;
    221     }
    222     if (section_header->sh_type == SHT_RELA) {
    223       has_rela_relocations = true;
    224     }
    225 
    226     // Note special sections as we encounter them.
    227     if ((name == ".rel.dyn" || name == ".rela.dyn") &&
    228         section_header->sh_size > 0) {
    229       found_relocations_section = section;
    230     }
    231     if ((name == ".android.rel.dyn" || name == ".android.rela.dyn") &&
    232         section_header->sh_size > 0) {
    233       found_android_relocations_section = section;
    234     }
    235     if (section_header->sh_offset == dynamic_program_header->p_offset) {
    236       found_dynamic_section = section;
    237     }
    238 
    239     // Ensure we preserve alignment, repeated later for the data block(s).
    240     CHECK(section_header->sh_addralign <= kPreserveAlignment);
    241 
    242     Elf_Data* data = NULL;
    243     while ((data = elf_getdata(section, data)) != NULL) {
    244       CHECK(data->d_align <= kPreserveAlignment);
    245       VerboseLogSectionData(data);
    246     }
    247   }
    248 
    249   // Loading failed if we did not find the required special sections.
    250   if (!found_relocations_section) {
    251     LOG(ERROR) << "Missing or empty .rel.dyn or .rela.dyn section";
    252     return false;
    253   }
    254   if (!found_android_relocations_section) {
    255     LOG(ERROR) << "Missing or empty .android.rel.dyn or .android.rela.dyn "
    256                << "section (to fix, run with --help and follow the "
    257                << "pre-packing instructions)";
    258     return false;
    259   }
    260   if (!found_dynamic_section) {
    261     LOG(ERROR) << "Missing .dynamic section";
    262     return false;
    263   }
    264 
    265   // Loading failed if we could not identify the relocations type.
    266   if (!has_rel_relocations && !has_rela_relocations) {
    267     LOG(ERROR) << "No relocations sections found";
    268     return false;
    269   }
    270   if (has_rel_relocations && has_rela_relocations) {
    271     LOG(ERROR) << "Multiple relocations sections with different types found, "
    272                << "not currently supported";
    273     return false;
    274   }
    275 
    276   elf_ = elf;
    277   relocations_section_ = found_relocations_section;
    278   dynamic_section_ = found_dynamic_section;
    279   android_relocations_section_ = found_android_relocations_section;
    280   relocations_type_ = has_rel_relocations ? REL : RELA;
    281   return true;
    282 }
    283 
    284 namespace {
    285 
    286 // Helper for ResizeSection().  Adjust the main ELF header for the hole.
    287 void AdjustElfHeaderForHole(ELF::Ehdr* elf_header,
    288                             ELF::Off hole_start,
    289                             ssize_t hole_size) {
    290   if (elf_header->e_phoff > hole_start) {
    291     elf_header->e_phoff += hole_size;
    292     VLOG(1) << "e_phoff adjusted to " << elf_header->e_phoff;
    293   }
    294   if (elf_header->e_shoff > hole_start) {
    295     elf_header->e_shoff += hole_size;
    296     VLOG(1) << "e_shoff adjusted to " << elf_header->e_shoff;
    297   }
    298 }
    299 
    300 // Helper for ResizeSection().  Adjust all section headers for the hole.
    301 void AdjustSectionHeadersForHole(Elf* elf,
    302                                  ELF::Off hole_start,
    303                                  ssize_t hole_size) {
    304   size_t string_index;
    305   elf_getshdrstrndx(elf, &string_index);
    306 
    307   Elf_Scn* section = NULL;
    308   while ((section = elf_nextscn(elf, section)) != NULL) {
    309     ELF::Shdr* section_header = ELF::getshdr(section);
    310     std::string name = elf_strptr(elf, string_index, section_header->sh_name);
    311 
    312     if (section_header->sh_offset > hole_start) {
    313       section_header->sh_offset += hole_size;
    314       VLOG(1) << "section " << name
    315               << " sh_offset adjusted to " << section_header->sh_offset;
    316     }
    317   }
    318 }
    319 
    320 // Helper for ResizeSection().  Adjust the offsets of any program headers
    321 // that have offsets currently beyond the hole start.
    322 void AdjustProgramHeaderOffsets(ELF::Phdr* program_headers,
    323                                 size_t count,
    324                                 ELF::Phdr* ignored_1,
    325                                 ELF::Phdr* ignored_2,
    326                                 ELF::Off hole_start,
    327                                 ssize_t hole_size) {
    328   for (size_t i = 0; i < count; ++i) {
    329     ELF::Phdr* program_header = &program_headers[i];
    330 
    331     if (program_header == ignored_1 || program_header == ignored_2)
    332       continue;
    333 
    334     if (program_header->p_offset > hole_start) {
    335       // The hole start is past this segment, so adjust offset.
    336       program_header->p_offset += hole_size;
    337       VLOG(1) << "phdr[" << i
    338               << "] p_offset adjusted to "<< program_header->p_offset;
    339     }
    340   }
    341 }
    342 
    343 // Helper for ResizeSection().  Find the first loadable segment in the
    344 // file.  We expect it to map from file offset zero.
    345 ELF::Phdr* FindFirstLoadSegment(ELF::Phdr* program_headers,
    346                                 size_t count) {
    347   ELF::Phdr* first_loadable_segment = NULL;
    348 
    349   for (size_t i = 0; i < count; ++i) {
    350     ELF::Phdr* program_header = &program_headers[i];
    351 
    352     if (program_header->p_type == PT_LOAD &&
    353         program_header->p_offset == 0 &&
    354         program_header->p_vaddr == 0 &&
    355         program_header->p_paddr == 0) {
    356       first_loadable_segment = program_header;
    357     }
    358   }
    359   LOG_IF(FATAL, !first_loadable_segment)
    360       << "Cannot locate a LOAD segment with address and offset zero";
    361 
    362   return first_loadable_segment;
    363 }
    364 
    365 // Helper for ResizeSection().  Find the PT_GNU_STACK segment, and check
    366 // that it contains what we expect so we can restore it on unpack if needed.
    367 ELF::Phdr* FindUnusedGnuStackSegment(ELF::Phdr* program_headers,
    368                                      size_t count) {
    369   ELF::Phdr* unused_segment = NULL;
    370 
    371   for (size_t i = 0; i < count; ++i) {
    372     ELF::Phdr* program_header = &program_headers[i];
    373 
    374     if (program_header->p_type == PT_GNU_STACK &&
    375         program_header->p_offset == 0 &&
    376         program_header->p_vaddr == 0 &&
    377         program_header->p_paddr == 0 &&
    378         program_header->p_filesz == 0 &&
    379         program_header->p_memsz == 0 &&
    380         program_header->p_flags == (PF_R | PF_W) &&
    381         program_header->p_align == ELF::kGnuStackSegmentAlignment) {
    382       unused_segment = program_header;
    383     }
    384   }
    385   LOG_IF(FATAL, !unused_segment)
    386       << "Cannot locate the expected GNU_STACK segment";
    387 
    388   return unused_segment;
    389 }
    390 
    391 // Helper for ResizeSection().  Find the segment that was the first loadable
    392 // one before we split it into two.  This is the one into which we coalesce
    393 // the split segments on unpacking.
    394 ELF::Phdr* FindOriginalFirstLoadSegment(ELF::Phdr* program_headers,
    395                                         size_t count) {
    396   const ELF::Phdr* first_loadable_segment =
    397       FindFirstLoadSegment(program_headers, count);
    398 
    399   ELF::Phdr* original_first_loadable_segment = NULL;
    400 
    401   for (size_t i = 0; i < count; ++i) {
    402     ELF::Phdr* program_header = &program_headers[i];
    403 
    404     // The original first loadable segment is the one that follows on from
    405     // the one we wrote on split to be the current first loadable segment.
    406     if (program_header->p_type == PT_LOAD &&
    407         program_header->p_offset == first_loadable_segment->p_filesz) {
    408       original_first_loadable_segment = program_header;
    409     }
    410   }
    411   LOG_IF(FATAL, !original_first_loadable_segment)
    412       << "Cannot locate the LOAD segment that follows a LOAD at offset zero";
    413 
    414   return original_first_loadable_segment;
    415 }
    416 
    417 // Helper for ResizeSection().  Find the segment that contains the hole.
    418 Elf_Scn* FindSectionContainingHole(Elf* elf,
    419                                    ELF::Off hole_start,
    420                                    ssize_t hole_size) {
    421   Elf_Scn* section = NULL;
    422   Elf_Scn* last_unholed_section = NULL;
    423 
    424   while ((section = elf_nextscn(elf, section)) != NULL) {
    425     const ELF::Shdr* section_header = ELF::getshdr(section);
    426 
    427     // Because we get here after section headers have been adjusted for the
    428     // hole, we need to 'undo' that adjustment to give a view of the original
    429     // sections layout.
    430     ELF::Off offset = section_header->sh_offset;
    431     if (section_header->sh_offset >= hole_start) {
    432       offset -= hole_size;
    433     }
    434 
    435     if (offset <= hole_start) {
    436       last_unholed_section = section;
    437     }
    438   }
    439   LOG_IF(FATAL, !last_unholed_section)
    440       << "Cannot identify the section before the one containing the hole";
    441 
    442   // The section containing the hole is the one after the last one found
    443   // by the loop above.
    444   Elf_Scn* holed_section = elf_nextscn(elf, last_unholed_section);
    445   LOG_IF(FATAL, !holed_section)
    446       << "Cannot identify the section containing the hole";
    447 
    448   return holed_section;
    449 }
    450 
    451 // Helper for ResizeSection().  Find the last section contained in a segment.
    452 Elf_Scn* FindLastSectionInSegment(Elf* elf,
    453                                   ELF::Phdr* program_header,
    454                                   ELF::Off hole_start,
    455                                   ssize_t hole_size) {
    456   const ELF::Off segment_end =
    457       program_header->p_offset + program_header->p_filesz;
    458 
    459   Elf_Scn* section = NULL;
    460   Elf_Scn* last_section = NULL;
    461 
    462   while ((section = elf_nextscn(elf, section)) != NULL) {
    463     const ELF::Shdr* section_header = ELF::getshdr(section);
    464 
    465     // As above, 'undo' any section offset adjustment to give a view of the
    466     // original sections layout.
    467     ELF::Off offset = section_header->sh_offset;
    468     if (section_header->sh_offset >= hole_start) {
    469       offset -= hole_size;
    470     }
    471 
    472     if (offset < segment_end) {
    473       last_section = section;
    474     }
    475   }
    476   LOG_IF(FATAL, !last_section)
    477       << "Cannot identify the last section in the given segment";
    478 
    479   return last_section;
    480 }
    481 
    482 // Helper for ResizeSection().  Order loadable segments by their offsets.
    483 // The crazy linker contains assumptions about loadable segment ordering,
    484 // and it is better if we do not break them.
    485 void SortOrderSensitiveProgramHeaders(ELF::Phdr* program_headers,
    486                                       size_t count) {
    487   std::vector<ELF::Phdr*> orderable;
    488 
    489   // Collect together orderable program headers.  These are all the LOAD
    490   // segments, and any GNU_STACK that may be present (removed on packing,
    491   // but replaced on unpacking).
    492   for (size_t i = 0; i < count; ++i) {
    493     ELF::Phdr* program_header = &program_headers[i];
    494 
    495     if (program_header->p_type == PT_LOAD ||
    496         program_header->p_type == PT_GNU_STACK) {
    497       orderable.push_back(program_header);
    498     }
    499   }
    500 
    501   // Order these program headers so that any PT_GNU_STACK is last, and
    502   // the LOAD segments that precede it appear in offset order.  Uses
    503   // insertion sort.
    504   for (size_t i = 1; i < orderable.size(); ++i) {
    505     for (size_t j = i; j > 0; --j) {
    506       ELF::Phdr* first = orderable[j - 1];
    507       ELF::Phdr* second = orderable[j];
    508 
    509       if (!(first->p_type == PT_GNU_STACK ||
    510             first->p_offset > second->p_offset)) {
    511         break;
    512       }
    513       std::swap(*first, *second);
    514     }
    515   }
    516 }
    517 
    518 // Helper for ResizeSection().  The GNU_STACK program header is unused in
    519 // Android, so we can repurpose it here.  Before packing, the program header
    520 // table contains something like:
    521 //
    522 //   Type      Offset    VirtAddr   PhysAddr   FileSiz   MemSiz    Flg Align
    523 //   LOAD      0x000000  0x00000000 0x00000000 0x1efc818 0x1efc818 R E 0x1000
    524 //   LOAD      0x1efd008 0x01efe008 0x01efe008 0x17ec3c  0x1a0324  RW  0x1000
    525 //   DYNAMIC   0x205ec50 0x0205fc50 0x0205fc50 0x00108   0x00108   RW  0x4
    526 //   GNU_STACK 0x000000  0x00000000 0x00000000 0x00000   0x00000   RW  0
    527 //
    528 // The hole in the file is in the first of these.  In order to preserve all
    529 // load addresses, what we do is to turn the GNU_STACK into a new LOAD entry
    530 // that maps segments up to where we created the hole, adjust the first LOAD
    531 // entry so that it maps segments after that, adjust any other program
    532 // headers whose offset is after the hole start, and finally order the LOAD
    533 // segments by offset, to give:
    534 //
    535 //   Type      Offset    VirtAddr   PhysAddr   FileSiz   MemSiz    Flg Align
    536 //   LOAD      0x000000  0x00000000 0x00000000 0x14ea4   0x14ea4   R E 0x1000
    537 //   LOAD      0x014ea4  0x00212ea4 0x00212ea4 0x1cea164 0x1cea164 R E 0x1000
    538 //   DYNAMIC   0x1e60c50 0x0205fc50 0x0205fc50 0x00108   0x00108   RW  0x4
    539 //   LOAD      0x1cff008 0x01efe008 0x01efe008 0x17ec3c  0x1a0324  RW  0x1000
    540 //
    541 // We work out the split points by finding the .rel.dyn or .rela.dyn section
    542 // that contains the hole, and by finding the last section in a given segment.
    543 //
    544 // To unpack, we reverse the above to leave the file as it was originally.
    545 void SplitProgramHeadersForHole(Elf* elf,
    546                                 ELF::Off hole_start,
    547                                 ssize_t hole_size) {
    548   CHECK(hole_size < 0);
    549   const ELF::Ehdr* elf_header = ELF::getehdr(elf);
    550   CHECK(elf_header);
    551 
    552   ELF::Phdr* elf_program_header = ELF::getphdr(elf);
    553   CHECK(elf_program_header);
    554 
    555   const size_t program_header_count = elf_header->e_phnum;
    556 
    557   // Locate the segment that we can overwrite to form the new LOAD entry,
    558   // and the segment that we are going to split into two parts.
    559   ELF::Phdr* spliced_header =
    560       FindUnusedGnuStackSegment(elf_program_header, program_header_count);
    561   ELF::Phdr* split_header =
    562       FindFirstLoadSegment(elf_program_header, program_header_count);
    563 
    564   VLOG(1) << "phdr[" << split_header - elf_program_header << "] split";
    565   VLOG(1) << "phdr[" << spliced_header - elf_program_header << "] new LOAD";
    566 
    567   // Find the section that contains the hole.  We split on the section that
    568   // follows it.
    569   Elf_Scn* holed_section =
    570       FindSectionContainingHole(elf, hole_start, hole_size);
    571 
    572   size_t string_index;
    573   elf_getshdrstrndx(elf, &string_index);
    574 
    575   ELF::Shdr* section_header = ELF::getshdr(holed_section);
    576   std::string name = elf_strptr(elf, string_index, section_header->sh_name);
    577   VLOG(1) << "section " << name << " split after";
    578 
    579   // Find the last section in the segment we are splitting.
    580   Elf_Scn* last_section =
    581       FindLastSectionInSegment(elf, split_header, hole_start, hole_size);
    582 
    583   section_header = ELF::getshdr(last_section);
    584   name = elf_strptr(elf, string_index, section_header->sh_name);
    585   VLOG(1) << "section " << name << " split end";
    586 
    587   // Split on the section following the holed one, and up to (but not
    588   // including) the section following the last one in the split segment.
    589   Elf_Scn* split_section = elf_nextscn(elf, holed_section);
    590   LOG_IF(FATAL, !split_section)
    591       << "No section follows the section that contains the hole";
    592   Elf_Scn* end_section = elf_nextscn(elf, last_section);
    593   LOG_IF(FATAL, !end_section)
    594       << "No section follows the last section in the segment being split";
    595 
    596   // Split the first portion of split_header into spliced_header.
    597   const ELF::Shdr* split_section_header = ELF::getshdr(split_section);
    598   spliced_header->p_type = split_header->p_type;
    599   spliced_header->p_offset = split_header->p_offset;
    600   spliced_header->p_vaddr = split_header->p_vaddr;
    601   spliced_header->p_paddr = split_header->p_paddr;
    602   CHECK(split_header->p_filesz == split_header->p_memsz);
    603   spliced_header->p_filesz = split_section_header->sh_offset;
    604   spliced_header->p_memsz = split_section_header->sh_offset;
    605   spliced_header->p_flags = split_header->p_flags;
    606   spliced_header->p_align = split_header->p_align;
    607 
    608   // Now rewrite split_header to remove the part we spliced from it.
    609   const ELF::Shdr* end_section_header = ELF::getshdr(end_section);
    610   split_header->p_offset = spliced_header->p_filesz;
    611   CHECK(split_header->p_vaddr == split_header->p_paddr);
    612   split_header->p_vaddr = split_section_header->sh_addr;
    613   split_header->p_paddr = split_section_header->sh_addr;
    614   CHECK(split_header->p_filesz == split_header->p_memsz);
    615   split_header->p_filesz =
    616       end_section_header->sh_offset - spliced_header->p_filesz;
    617   split_header->p_memsz =
    618       end_section_header->sh_offset - spliced_header->p_filesz;
    619 
    620   // Adjust the offsets of all program headers that are not one of the pair
    621   // we just created by splitting.
    622   AdjustProgramHeaderOffsets(elf_program_header,
    623                              program_header_count,
    624                              spliced_header,
    625                              split_header,
    626                              hole_start,
    627                              hole_size);
    628 
    629   // Finally, order loadable segments by offset/address.  The crazy linker
    630   // contains assumptions about loadable segment ordering.
    631   SortOrderSensitiveProgramHeaders(elf_program_header,
    632                                    program_header_count);
    633 }
    634 
    635 // Helper for ResizeSection().  Undo the work of SplitProgramHeadersForHole().
    636 void CoalesceProgramHeadersForHole(Elf* elf,
    637                                    ELF::Off hole_start,
    638                                    ssize_t hole_size) {
    639   CHECK(hole_size > 0);
    640   const ELF::Ehdr* elf_header = ELF::getehdr(elf);
    641   CHECK(elf_header);
    642 
    643   ELF::Phdr* elf_program_header = ELF::getphdr(elf);
    644   CHECK(elf_program_header);
    645 
    646   const size_t program_header_count = elf_header->e_phnum;
    647 
    648   // Locate the segment that we overwrote to form the new LOAD entry, and
    649   // the segment that we split into two parts on packing.
    650   ELF::Phdr* spliced_header =
    651       FindFirstLoadSegment(elf_program_header, program_header_count);
    652   ELF::Phdr* split_header =
    653       FindOriginalFirstLoadSegment(elf_program_header, program_header_count);
    654 
    655   VLOG(1) << "phdr[" << spliced_header - elf_program_header << "] stack";
    656   VLOG(1) << "phdr[" << split_header - elf_program_header << "] coalesce";
    657 
    658   // Find the last section in the second segment we are coalescing.
    659   Elf_Scn* last_section =
    660       FindLastSectionInSegment(elf, split_header, hole_start, hole_size);
    661 
    662   size_t string_index;
    663   elf_getshdrstrndx(elf, &string_index);
    664 
    665   const ELF::Shdr* section_header = ELF::getshdr(last_section);
    666   std::string name = elf_strptr(elf, string_index, section_header->sh_name);
    667   VLOG(1) << "section " << name << " coalesced";
    668 
    669   // Rewrite the coalesced segment into split_header.
    670   const ELF::Shdr* last_section_header = ELF::getshdr(last_section);
    671   split_header->p_offset = spliced_header->p_offset;
    672   CHECK(split_header->p_vaddr == split_header->p_paddr);
    673   split_header->p_vaddr = spliced_header->p_vaddr;
    674   split_header->p_paddr = spliced_header->p_vaddr;
    675   CHECK(split_header->p_filesz == split_header->p_memsz);
    676   split_header->p_filesz =
    677       last_section_header->sh_offset + last_section_header->sh_size;
    678   split_header->p_memsz =
    679       last_section_header->sh_offset + last_section_header->sh_size;
    680 
    681   // Reconstruct the original GNU_STACK segment into spliced_header.
    682   spliced_header->p_type = PT_GNU_STACK;
    683   spliced_header->p_offset = 0;
    684   spliced_header->p_vaddr = 0;
    685   spliced_header->p_paddr = 0;
    686   spliced_header->p_filesz = 0;
    687   spliced_header->p_memsz = 0;
    688   spliced_header->p_flags = PF_R | PF_W;
    689   spliced_header->p_align = ELF::kGnuStackSegmentAlignment;
    690 
    691   // Adjust the offsets of all program headers that are not one of the pair
    692   // we just coalesced.
    693   AdjustProgramHeaderOffsets(elf_program_header,
    694                              program_header_count,
    695                              spliced_header,
    696                              split_header,
    697                              hole_start,
    698                              hole_size);
    699 
    700   // Finally, order loadable segments by offset/address.  The crazy linker
    701   // contains assumptions about loadable segment ordering.
    702   SortOrderSensitiveProgramHeaders(elf_program_header,
    703                                    program_header_count);
    704 }
    705 
    706 // Helper for ResizeSection().  Rewrite program headers.
    707 void RewriteProgramHeadersForHole(Elf* elf,
    708                                   ELF::Off hole_start,
    709                                   ssize_t hole_size) {
    710   // If hole_size is negative then we are removing a piece of the file, and
    711   // we want to split program headers so that we keep the same addresses
    712   // for text and data.  If positive, then we are putting that piece of the
    713   // file back in, so we coalesce the previously split program headers.
    714   if (hole_size < 0)
    715     SplitProgramHeadersForHole(elf, hole_start, hole_size);
    716   else if (hole_size > 0)
    717     CoalesceProgramHeadersForHole(elf, hole_start, hole_size);
    718 }
    719 
    720 // Helper for ResizeSection().  Locate and return the dynamic section.
    721 Elf_Scn* GetDynamicSection(Elf* elf) {
    722   const ELF::Ehdr* elf_header = ELF::getehdr(elf);
    723   CHECK(elf_header);
    724 
    725   const ELF::Phdr* elf_program_header = ELF::getphdr(elf);
    726   CHECK(elf_program_header);
    727 
    728   // Find the program header that describes the dynamic section.
    729   const ELF::Phdr* dynamic_program_header = NULL;
    730   for (size_t i = 0; i < elf_header->e_phnum; ++i) {
    731     const ELF::Phdr* program_header = &elf_program_header[i];
    732 
    733     if (program_header->p_type == PT_DYNAMIC) {
    734       dynamic_program_header = program_header;
    735     }
    736   }
    737   CHECK(dynamic_program_header);
    738 
    739   // Now find the section with the same offset as this program header.
    740   Elf_Scn* dynamic_section = NULL;
    741   Elf_Scn* section = NULL;
    742   while ((section = elf_nextscn(elf, section)) != NULL) {
    743     ELF::Shdr* section_header = ELF::getshdr(section);
    744 
    745     if (section_header->sh_offset == dynamic_program_header->p_offset) {
    746       dynamic_section = section;
    747     }
    748   }
    749   CHECK(dynamic_section != NULL);
    750 
    751   return dynamic_section;
    752 }
    753 
    754 // Helper for ResizeSection().  Adjust the .dynamic section for the hole.
    755 template <typename Rel>
    756 void AdjustDynamicSectionForHole(Elf_Scn* dynamic_section,
    757                                  ELF::Off hole_start,
    758                                  ssize_t hole_size) {
    759   Elf_Data* data = GetSectionData(dynamic_section);
    760 
    761   const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
    762   std::vector<ELF::Dyn> dynamics(
    763       dynamic_base,
    764       dynamic_base + data->d_size / sizeof(dynamics[0]));
    765 
    766   for (size_t i = 0; i < dynamics.size(); ++i) {
    767     ELF::Dyn* dynamic = &dynamics[i];
    768     const ELF::Sword tag = dynamic->d_tag;
    769 
    770     // DT_RELSZ or DT_RELASZ indicate the overall size of relocations.
    771     // Only one will be present.  Adjust by hole size.
    772     if (tag == DT_RELSZ || tag == DT_RELASZ) {
    773       dynamic->d_un.d_val += hole_size;
    774       VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
    775               << " d_val adjusted to " << dynamic->d_un.d_val;
    776     }
    777 
    778     // DT_RELCOUNT or DT_RELACOUNT hold the count of relative relocations.
    779     // Only one will be present.  Packing reduces it to the alignment
    780     // padding, if any; unpacking restores it to its former value.  The
    781     // crazy linker does not use it, but we update it anyway.
    782     if (tag == DT_RELCOUNT || tag == DT_RELACOUNT) {
    783       // Cast sizeof to a signed type to avoid the division result being
    784       // promoted into an unsigned size_t.
    785       const ssize_t sizeof_rel = static_cast<ssize_t>(sizeof(Rel));
    786       dynamic->d_un.d_val += hole_size / sizeof_rel;
    787       VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
    788               << " d_val adjusted to " << dynamic->d_un.d_val;
    789     }
    790 
    791     // DT_RELENT and DT_RELAENT do not change, but make sure they are what
    792     // we expect.  Only one will be present.
    793     if (tag == DT_RELENT || tag == DT_RELAENT) {
    794       CHECK(dynamic->d_un.d_val == sizeof(Rel));
    795     }
    796   }
    797 
    798   void* section_data = &dynamics[0];
    799   size_t bytes = dynamics.size() * sizeof(dynamics[0]);
    800   RewriteSectionData(data, section_data, bytes);
    801 }
    802 
    803 // Resize a section.  If the new size is larger than the current size, open
    804 // up a hole by increasing file offsets that come after the hole.  If smaller
    805 // than the current size, remove the hole by decreasing those offsets.
    806 template <typename Rel>
    807 void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size) {
    808   ELF::Shdr* section_header = ELF::getshdr(section);
    809   if (section_header->sh_size == new_size)
    810     return;
    811 
    812   // Note if we are resizing the real dyn relocations.
    813   size_t string_index;
    814   elf_getshdrstrndx(elf, &string_index);
    815   const std::string section_name =
    816       elf_strptr(elf, string_index, section_header->sh_name);
    817   const bool is_relocations_resize =
    818       (section_name == ".rel.dyn" || section_name == ".rela.dyn");
    819 
    820   // Require that the section size and the data size are the same.  True
    821   // in practice for all sections we resize when packing or unpacking.
    822   Elf_Data* data = GetSectionData(section);
    823   CHECK(data->d_off == 0 && data->d_size == section_header->sh_size);
    824 
    825   // Require that the section is not zero-length (that is, has allocated
    826   // data that we can validly expand).
    827   CHECK(data->d_size && data->d_buf);
    828 
    829   const ELF::Off hole_start = section_header->sh_offset;
    830   const ssize_t hole_size = new_size - data->d_size;
    831 
    832   VLOG_IF(1, (hole_size > 0)) << "expand section size = " << data->d_size;
    833   VLOG_IF(1, (hole_size < 0)) << "shrink section size = " << data->d_size;
    834 
    835   // Resize the data and the section header.
    836   data->d_size += hole_size;
    837   section_header->sh_size += hole_size;
    838 
    839   // Add the hole size to all offsets in the ELF file that are after the
    840   // start of the hole.  If the hole size is positive we are expanding the
    841   // section to create a new hole; if negative, we are closing up a hole.
    842 
    843   // Start with the main ELF header.
    844   ELF::Ehdr* elf_header = ELF::getehdr(elf);
    845   AdjustElfHeaderForHole(elf_header, hole_start, hole_size);
    846 
    847   // Adjust all section headers.
    848   AdjustSectionHeadersForHole(elf, hole_start, hole_size);
    849 
    850   // If resizing the dynamic relocations, rewrite the program headers to
    851   // either split or coalesce segments, and adjust dynamic entries to match.
    852   if (is_relocations_resize) {
    853     RewriteProgramHeadersForHole(elf, hole_start, hole_size);
    854 
    855     Elf_Scn* dynamic_section = GetDynamicSection(elf);
    856     AdjustDynamicSectionForHole<Rel>(dynamic_section, hole_start, hole_size);
    857   }
    858 }
    859 
    860 // Find the first slot in a dynamics array with the given tag.  The array
    861 // always ends with a free (unused) element, and which we exclude from the
    862 // search.  Returns dynamics->size() if not found.
    863 size_t FindDynamicEntry(ELF::Sword tag,
    864                         std::vector<ELF::Dyn>* dynamics) {
    865   // Loop until the penultimate entry.  We exclude the end sentinel.
    866   for (size_t i = 0; i < dynamics->size() - 1; ++i) {
    867     if (dynamics->at(i).d_tag == tag)
    868       return i;
    869   }
    870 
    871   // The tag was not found.
    872   return dynamics->size();
    873 }
    874 
    875 // Replace the first free (unused) slot in a dynamics vector with the given
    876 // value.  The vector always ends with a free (unused) element, so the slot
    877 // found cannot be the last one in the vector.
    878 void AddDynamicEntry(const ELF::Dyn& dyn,
    879                      std::vector<ELF::Dyn>* dynamics) {
    880   const size_t slot = FindDynamicEntry(DT_NULL, dynamics);
    881   if (slot == dynamics->size()) {
    882     LOG(FATAL) << "No spare dynamic array slots found "
    883                << "(to fix, increase gold's --spare-dynamic-tags value)";
    884   }
    885 
    886   // Replace this entry with the one supplied.
    887   dynamics->at(slot) = dyn;
    888   VLOG(1) << "dynamic[" << slot << "] overwritten with " << dyn.d_tag;
    889 }
    890 
    891 // Remove the element in the dynamics vector that matches the given tag with
    892 // unused slot data.  Shuffle the following elements up, and ensure that the
    893 // last is the null sentinel.
    894 void RemoveDynamicEntry(ELF::Sword tag,
    895                         std::vector<ELF::Dyn>* dynamics) {
    896   const size_t slot = FindDynamicEntry(tag, dynamics);
    897   CHECK(slot != dynamics->size());
    898 
    899   // Remove this entry by shuffling up everything that follows.
    900   for (size_t i = slot; i < dynamics->size() - 1; ++i) {
    901     dynamics->at(i) = dynamics->at(i + 1);
    902     VLOG(1) << "dynamic[" << i
    903             << "] overwritten with dynamic[" << i + 1 << "]";
    904   }
    905 
    906   // Ensure that the end sentinel is still present.
    907   CHECK(dynamics->at(dynamics->size() - 1).d_tag == DT_NULL);
    908 }
    909 
    910 template <typename Rel>
    911 void PadRelocations(size_t count, std::vector<Rel>* relocations);
    912 
    913 template <>
    914 void PadRelocations<ELF::Rel>(size_t count,
    915                               std::vector<ELF::Rel>* relocations) {
    916   ELF::Rel null_relocation;
    917   null_relocation.r_offset = 0;
    918   null_relocation.r_info = ELF_R_INFO(0, ELF::kNoRelocationCode);
    919   std::vector<ELF::Rel> padding(count, null_relocation);
    920   relocations->insert(relocations->end(), padding.begin(), padding.end());
    921 }
    922 
    923 template <>
    924 void PadRelocations<ELF::Rela>(size_t count,
    925                                std::vector<ELF::Rela>* relocations) {
    926   ELF::Rela null_relocation;
    927   null_relocation.r_offset = 0;
    928   null_relocation.r_info = ELF_R_INFO(0, ELF::kNoRelocationCode);
    929   null_relocation.r_addend = 0;
    930   std::vector<ELF::Rela> padding(count, null_relocation);
    931   relocations->insert(relocations->end(), padding.begin(), padding.end());
    932 }
    933 
    934 }  // namespace
    935 
    936 // Remove relative entries from dynamic relocations and write as packed
    937 // data into android packed relocations.
    938 bool ElfFile::PackRelocations() {
    939   // Load the ELF file into libelf.
    940   if (!Load()) {
    941     LOG(ERROR) << "Failed to load as ELF";
    942     return false;
    943   }
    944 
    945   // Retrieve the current dynamic relocations section data.
    946   Elf_Data* data = GetSectionData(relocations_section_);
    947 
    948   if (relocations_type_ == REL) {
    949     // Convert data to a vector of relocations.
    950     const ELF::Rel* relocations_base = reinterpret_cast<ELF::Rel*>(data->d_buf);
    951     std::vector<ELF::Rel> relocations(
    952         relocations_base,
    953         relocations_base + data->d_size / sizeof(relocations[0]));
    954 
    955     LOG(INFO) << "Relocations   : REL";
    956     return PackTypedRelocations<ELF::Rel>(relocations, data);
    957   }
    958 
    959   if (relocations_type_ == RELA) {
    960     // Convert data to a vector of relocations with addends.
    961     const ELF::Rela* relocations_base =
    962         reinterpret_cast<ELF::Rela*>(data->d_buf);
    963     std::vector<ELF::Rela> relocations(
    964         relocations_base,
    965         relocations_base + data->d_size / sizeof(relocations[0]));
    966 
    967     LOG(INFO) << "Relocations   : RELA";
    968     return PackTypedRelocations<ELF::Rela>(relocations, data);
    969   }
    970 
    971   NOTREACHED();
    972   return false;
    973 }
    974 
    975 // Helper for PackRelocations().  Rel type is one of ELF::Rel or ELF::Rela.
    976 template <typename Rel>
    977 bool ElfFile::PackTypedRelocations(const std::vector<Rel>& relocations,
    978                                    Elf_Data* data) {
    979   // Filter relocations into those that are relative and others.
    980   std::vector<Rel> relative_relocations;
    981   std::vector<Rel> other_relocations;
    982 
    983   for (size_t i = 0; i < relocations.size(); ++i) {
    984     const Rel& relocation = relocations[i];
    985     if (ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode) {
    986       CHECK(ELF_R_SYM(relocation.r_info) == 0);
    987       relative_relocations.push_back(relocation);
    988     } else {
    989       other_relocations.push_back(relocation);
    990     }
    991   }
    992   LOG(INFO) << "Relative      : " << relative_relocations.size() << " entries";
    993   LOG(INFO) << "Other         : " << other_relocations.size() << " entries";
    994   LOG(INFO) << "Total         : " << relocations.size() << " entries";
    995 
    996   // If no relative relocations then we have nothing packable.  Perhaps
    997   // the shared object has already been packed?
    998   if (relative_relocations.empty()) {
    999     LOG(ERROR) << "No relative relocations found (already packed?)";
   1000     return false;
   1001   }
   1002 
   1003   // If not padding fully, apply only enough padding to preserve alignment.
   1004   // Otherwise, pad so that we do not shrink the relocations section at all.
   1005   if (!is_padding_relocations_) {
   1006     // Calculate the size of the hole we will close up when we rewrite
   1007     // dynamic relocations.
   1008     ELF::Shdr* section_header = ELF::getshdr(relocations_section_);
   1009     const ELF::Off hole_start = section_header->sh_offset;
   1010     ssize_t hole_size =
   1011         relative_relocations.size() * sizeof(relative_relocations[0]);
   1012     const ssize_t unaligned_hole_size = hole_size;
   1013 
   1014     // Adjust the actual hole size to preserve alignment.  We always adjust
   1015     // by a whole number of NONE-type relocations.
   1016     while (hole_size % kPreserveAlignment)
   1017       hole_size -= sizeof(relative_relocations[0]);
   1018     LOG(INFO) << "Compaction    : " << hole_size << " bytes";
   1019 
   1020     // Adjusting for alignment may have removed any packing benefit.
   1021     if (hole_size == 0) {
   1022       LOG(INFO) << "Too few relative relocations to pack after alignment";
   1023       return false;
   1024     }
   1025 
   1026     // Find the padding needed in other_relocations to preserve alignment.
   1027     // Ensure that we never completely empty the real relocations section.
   1028     size_t padding_bytes = unaligned_hole_size - hole_size;
   1029     if (padding_bytes == 0 && other_relocations.size() == 0) {
   1030       do {
   1031         padding_bytes += sizeof(relative_relocations[0]);
   1032       } while (padding_bytes % kPreserveAlignment);
   1033     }
   1034     CHECK(padding_bytes % sizeof(other_relocations[0]) == 0);
   1035     const size_t padding = padding_bytes / sizeof(other_relocations[0]);
   1036 
   1037     // Padding may have removed any packing benefit.
   1038     if (padding >= relative_relocations.size()) {
   1039       LOG(INFO) << "Too few relative relocations to pack after padding";
   1040       return false;
   1041     }
   1042 
   1043     // Add null relocations to other_relocations to preserve alignment.
   1044     PadRelocations<Rel>(padding, &other_relocations);
   1045     LOG(INFO) << "Alignment pad : " << padding << " relocations";
   1046   } else {
   1047     // If padding, add NONE-type relocations to other_relocations to make it
   1048     // the same size as the the original relocations we read in.  This makes
   1049     // the ResizeSection() below a no-op.
   1050     const size_t padding = relocations.size() - other_relocations.size();
   1051     PadRelocations<Rel>(padding, &other_relocations);
   1052   }
   1053 
   1054   // Pack relative relocations.
   1055   const size_t initial_bytes =
   1056       relative_relocations.size() * sizeof(relative_relocations[0]);
   1057   LOG(INFO) << "Unpacked relative: " << initial_bytes << " bytes";
   1058   std::vector<uint8_t> packed;
   1059   RelocationPacker packer;
   1060   packer.PackRelativeRelocations(relative_relocations, &packed);
   1061   const void* packed_data = &packed[0];
   1062   const size_t packed_bytes = packed.size() * sizeof(packed[0]);
   1063   LOG(INFO) << "Packed   relative: " << packed_bytes << " bytes";
   1064 
   1065   // If we have insufficient relative relocations to form a run then
   1066   // packing fails.
   1067   if (packed.empty()) {
   1068     LOG(INFO) << "Too few relative relocations to pack";
   1069     return false;
   1070   }
   1071 
   1072   // Run a loopback self-test as a check that packing is lossless.
   1073   std::vector<Rel> unpacked;
   1074   packer.UnpackRelativeRelocations(packed, &unpacked);
   1075   CHECK(unpacked.size() == relative_relocations.size());
   1076   CHECK(!memcmp(&unpacked[0],
   1077                 &relative_relocations[0],
   1078                 unpacked.size() * sizeof(unpacked[0])));
   1079 
   1080   // Make sure packing saved some space.
   1081   if (packed_bytes >= initial_bytes) {
   1082     LOG(INFO) << "Packing relative relocations saves no space";
   1083     return false;
   1084   }
   1085 
   1086   // Rewrite the current dynamic relocations section to be only the ARM
   1087   // non-relative relocations, then shrink it to size.
   1088   const void* section_data = &other_relocations[0];
   1089   const size_t bytes = other_relocations.size() * sizeof(other_relocations[0]);
   1090   ResizeSection<Rel>(elf_, relocations_section_, bytes);
   1091   RewriteSectionData(data, section_data, bytes);
   1092 
   1093   // Rewrite the current packed android relocations section to hold the packed
   1094   // relative relocations.
   1095   data = GetSectionData(android_relocations_section_);
   1096   ResizeSection<Rel>(elf_, android_relocations_section_, packed_bytes);
   1097   RewriteSectionData(data, packed_data, packed_bytes);
   1098 
   1099   // Rewrite .dynamic to include two new tags describing the packed android
   1100   // relocations.
   1101   data = GetSectionData(dynamic_section_);
   1102   const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
   1103   std::vector<ELF::Dyn> dynamics(
   1104       dynamic_base,
   1105       dynamic_base + data->d_size / sizeof(dynamics[0]));
   1106   // Use two of the spare slots to describe the packed section.
   1107   ELF::Shdr* section_header = ELF::getshdr(android_relocations_section_);
   1108   {
   1109     ELF::Dyn dyn;
   1110     dyn.d_tag = DT_ANDROID_REL_OFFSET;
   1111     dyn.d_un.d_ptr = section_header->sh_offset;
   1112     AddDynamicEntry(dyn, &dynamics);
   1113   }
   1114   {
   1115     ELF::Dyn dyn;
   1116     dyn.d_tag = DT_ANDROID_REL_SIZE;
   1117     dyn.d_un.d_val = section_header->sh_size;
   1118     AddDynamicEntry(dyn, &dynamics);
   1119   }
   1120   const void* dynamics_data = &dynamics[0];
   1121   const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
   1122   RewriteSectionData(data, dynamics_data, dynamics_bytes);
   1123 
   1124   Flush();
   1125   return true;
   1126 }
   1127 
   1128 // Find packed relative relocations in the packed android relocations
   1129 // section, unpack them, and rewrite the dynamic relocations section to
   1130 // contain unpacked data.
   1131 bool ElfFile::UnpackRelocations() {
   1132   // Load the ELF file into libelf.
   1133   if (!Load()) {
   1134     LOG(ERROR) << "Failed to load as ELF";
   1135     return false;
   1136   }
   1137 
   1138   // Retrieve the current packed android relocations section data.
   1139   Elf_Data* data = GetSectionData(android_relocations_section_);
   1140 
   1141   // Convert data to a vector of bytes.
   1142   const uint8_t* packed_base = reinterpret_cast<uint8_t*>(data->d_buf);
   1143   std::vector<uint8_t> packed(
   1144       packed_base,
   1145       packed_base + data->d_size / sizeof(packed[0]));
   1146 
   1147   if (packed.size() > 3 &&
   1148       packed[0] == 'A' &&
   1149       packed[1] == 'P' &&
   1150       packed[2] == 'R' &&
   1151       packed[3] == '1') {
   1152     // Signature is APR1, unpack relocations.
   1153     CHECK(relocations_type_ == REL);
   1154     LOG(INFO) << "Relocations   : REL";
   1155     return UnpackTypedRelocations<ELF::Rel>(packed, data);
   1156   }
   1157 
   1158   if (packed.size() > 3 &&
   1159       packed[0] == 'A' &&
   1160       packed[1] == 'P' &&
   1161       packed[2] == 'A' &&
   1162       packed[3] == '1') {
   1163     // Signature is APA1, unpack relocations with addends.
   1164     CHECK(relocations_type_ == RELA);
   1165     LOG(INFO) << "Relocations   : RELA";
   1166     return UnpackTypedRelocations<ELF::Rela>(packed, data);
   1167   }
   1168 
   1169   LOG(ERROR) << "Packed relative relocations not found (not packed?)";
   1170   return false;
   1171 }
   1172 
   1173 // Helper for UnpackRelocations().  Rel type is one of ELF::Rel or ELF::Rela.
   1174 template <typename Rel>
   1175 bool ElfFile::UnpackTypedRelocations(const std::vector<uint8_t>& packed,
   1176                                      Elf_Data* data) {
   1177   // Unpack the data to re-materialize the relative relocations.
   1178   const size_t packed_bytes = packed.size() * sizeof(packed[0]);
   1179   LOG(INFO) << "Packed   relative: " << packed_bytes << " bytes";
   1180   std::vector<Rel> relative_relocations;
   1181   RelocationPacker packer;
   1182   packer.UnpackRelativeRelocations(packed, &relative_relocations);
   1183   const size_t unpacked_bytes =
   1184       relative_relocations.size() * sizeof(relative_relocations[0]);
   1185   LOG(INFO) << "Unpacked relative: " << unpacked_bytes << " bytes";
   1186 
   1187   // Retrieve the current dynamic relocations section data.
   1188   data = GetSectionData(relocations_section_);
   1189 
   1190   // Interpret data as relocations.
   1191   const Rel* relocations_base = reinterpret_cast<Rel*>(data->d_buf);
   1192   std::vector<Rel> relocations(
   1193       relocations_base,
   1194       relocations_base + data->d_size / sizeof(relocations[0]));
   1195 
   1196   std::vector<Rel> other_relocations;
   1197   size_t padding = 0;
   1198 
   1199   // Filter relocations to locate any that are NONE-type.  These will occur
   1200   // if padding was turned on for packing.
   1201   for (size_t i = 0; i < relocations.size(); ++i) {
   1202     const Rel& relocation = relocations[i];
   1203     if (ELF_R_TYPE(relocation.r_info) != ELF::kNoRelocationCode) {
   1204       other_relocations.push_back(relocation);
   1205     } else {
   1206       ++padding;
   1207     }
   1208   }
   1209   LOG(INFO) << "Relative      : " << relative_relocations.size() << " entries";
   1210   LOG(INFO) << "Other         : " << other_relocations.size() << " entries";
   1211 
   1212   // If we found the same number of null relocation entries in the dynamic
   1213   // relocations section as we hold as unpacked relative relocations, then
   1214   // this is a padded file.
   1215   const bool is_padded = padding == relative_relocations.size();
   1216 
   1217   // Unless padded, pre-apply relative relocations to account for the
   1218   // hole, and pre-adjust all relocation offsets accordingly.
   1219   if (!is_padded) {
   1220     // Pre-calculate the size of the hole we will open up when we rewrite
   1221     // dynamic relocations.  We have to adjust relocation addresses to
   1222     // account for this.
   1223     ELF::Shdr* section_header = ELF::getshdr(relocations_section_);
   1224     const ELF::Off hole_start = section_header->sh_offset;
   1225     ssize_t hole_size =
   1226         relative_relocations.size() * sizeof(relative_relocations[0]);
   1227 
   1228     // Adjust the hole size for the padding added to preserve alignment.
   1229     hole_size -= padding * sizeof(other_relocations[0]);
   1230     LOG(INFO) << "Expansion     : " << hole_size << " bytes";
   1231   }
   1232 
   1233   // Rewrite the current dynamic relocations section to be the relative
   1234   // relocations followed by other relocations.  This is the usual order in
   1235   // which we find them after linking, so this action will normally put the
   1236   // entire dynamic relocations section back to its pre-split-and-packed state.
   1237   relocations.assign(relative_relocations.begin(), relative_relocations.end());
   1238   relocations.insert(relocations.end(),
   1239                      other_relocations.begin(), other_relocations.end());
   1240   const void* section_data = &relocations[0];
   1241   const size_t bytes = relocations.size() * sizeof(relocations[0]);
   1242   LOG(INFO) << "Total         : " << relocations.size() << " entries";
   1243   ResizeSection<Rel>(elf_, relocations_section_, bytes);
   1244   RewriteSectionData(data, section_data, bytes);
   1245 
   1246   // Nearly empty the current packed android relocations section.  Leaves a
   1247   // four-byte stub so that some data remains allocated to the section.
   1248   // This is a convenience which allows us to re-pack this file again without
   1249   // having to remove the section and then add a new small one with objcopy.
   1250   // The way we resize sections relies on there being some data in a section.
   1251   data = GetSectionData(android_relocations_section_);
   1252   ResizeSection<Rel>(
   1253       elf_, android_relocations_section_, sizeof(kStubIdentifier));
   1254   RewriteSectionData(data, &kStubIdentifier, sizeof(kStubIdentifier));
   1255 
   1256   // Rewrite .dynamic to remove two tags describing packed android relocations.
   1257   data = GetSectionData(dynamic_section_);
   1258   const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
   1259   std::vector<ELF::Dyn> dynamics(
   1260       dynamic_base,
   1261       dynamic_base + data->d_size / sizeof(dynamics[0]));
   1262   RemoveDynamicEntry(DT_ANDROID_REL_OFFSET, &dynamics);
   1263   RemoveDynamicEntry(DT_ANDROID_REL_SIZE, &dynamics);
   1264   const void* dynamics_data = &dynamics[0];
   1265   const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
   1266   RewriteSectionData(data, dynamics_data, dynamics_bytes);
   1267 
   1268   Flush();
   1269   return true;
   1270 }
   1271 
   1272 // Flush rewritten shared object file data.
   1273 void ElfFile::Flush() {
   1274   // Flag all ELF data held in memory as needing to be written back to the
   1275   // file, and tell libelf that we have controlled the file layout.
   1276   elf_flagelf(elf_, ELF_C_SET, ELF_F_DIRTY);
   1277   elf_flagelf(elf_, ELF_C_SET, ELF_F_LAYOUT);
   1278 
   1279   // Write ELF data back to disk.
   1280   const off_t file_bytes = elf_update(elf_, ELF_C_WRITE);
   1281   CHECK(file_bytes > 0);
   1282   VLOG(1) << "elf_update returned: " << file_bytes;
   1283 
   1284   // Clean up libelf, and truncate the output file to the number of bytes
   1285   // written by elf_update().
   1286   elf_end(elf_);
   1287   elf_ = NULL;
   1288   const int truncate = ftruncate(fd_, file_bytes);
   1289   CHECK(truncate == 0);
   1290 }
   1291 
   1292 }  // namespace relocation_packer
   1293