// 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.

// Implementation notes:
//
// We need to remove a piece from the ELF shared library.  However, we also
// want to ensure that code and data loads at the same addresses as before
// packing, so that tools like breakpad can still match up addresses found
// in any crash dumps with data extracted from the pre-packed version of
// the shared library.
//
// Arranging this means that we have to split one of the LOAD segments into
// two.  Unfortunately, the program headers are located at the very start
// of the shared library file, so expanding the program header section
// would cause a lot of consequent changes to files offsets that we don't
// really want to have to handle.
//
// Luckily, though, there is a segment that is always present and always
// unused on Android; the GNU_STACK segment.  What we do is to steal that
// and repurpose it to be one of the split LOAD segments.  We then have to
// sort LOAD segments by offset to keep the crazy linker happy.
//
// All of this takes place in SplitProgramHeadersForHole(), used on packing,
// and is unraveled on unpacking in CoalesceProgramHeadersForHole().  See
// commentary on those functions for an example of this segment stealing
// in action.

#include "elf_file.h"

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <algorithm>
#include <string>
#include <vector>

#include "debug.h"
#include "elf_traits.h"
#include "libelf.h"
#include "packer.h"

namespace relocation_packer {

// Stub identifier written to 'null out' packed data, "NULL".
static const uint32_t kStubIdentifier = 0x4c4c554eu;

// Out-of-band dynamic tags used to indicate the offset and size of the
// android packed relocations section.
static const ELF::Sword DT_ANDROID_REL_OFFSET = DT_LOOS;
static const ELF::Sword DT_ANDROID_REL_SIZE = DT_LOOS + 1;

// Alignment to preserve, in bytes.  This must be at least as large as the
// largest d_align and sh_addralign values found in the loaded file.
// Out of caution for RELRO page alignment, we preserve to a complete target
// page.  See http://www.airs.com/blog/archives/189.
static const size_t kPreserveAlignment = 4096;

namespace {

// Get section data.  Checks that the section has exactly one data entry,
// so that the section size and the data size are the same.  True in
// practice for all sections we resize when packing or unpacking.  Done
// by ensuring that a call to elf_getdata(section, data) returns NULL as
// the next data entry.
Elf_Data* GetSectionData(Elf_Scn* section) {
  Elf_Data* data = elf_getdata(section, NULL);
  CHECK(data && elf_getdata(section, data) == NULL);
  return data;
}

// Rewrite section data.  Allocates new data and makes it the data element's
// buffer.  Relies on program exit to free allocated data.
void RewriteSectionData(Elf_Data* data,
                        const void* section_data,
                        size_t size) {
  CHECK(size == data->d_size);
  uint8_t* area = new uint8_t[size];
  memcpy(area, section_data, size);
  data->d_buf = area;
}

// Verbose ELF header logging.
void VerboseLogElfHeader(const ELF::Ehdr* elf_header) {
  VLOG(1) << "e_phoff = " << elf_header->e_phoff;
  VLOG(1) << "e_shoff = " << elf_header->e_shoff;
  VLOG(1) << "e_ehsize = " << elf_header->e_ehsize;
  VLOG(1) << "e_phentsize = " << elf_header->e_phentsize;
  VLOG(1) << "e_phnum = " << elf_header->e_phnum;
  VLOG(1) << "e_shnum = " << elf_header->e_shnum;
  VLOG(1) << "e_shstrndx = " << elf_header->e_shstrndx;
}

// Verbose ELF program header logging.
void VerboseLogProgramHeader(size_t program_header_index,
                             const ELF::Phdr* program_header) {
  std::string type;
  switch (program_header->p_type) {
    case PT_NULL: type = "NULL"; break;
    case PT_LOAD: type = "LOAD"; break;
    case PT_DYNAMIC: type = "DYNAMIC"; break;
    case PT_INTERP: type = "INTERP"; break;
    case PT_PHDR: type = "PHDR"; break;
    case PT_GNU_RELRO: type = "GNU_RELRO"; break;
    case PT_GNU_STACK: type = "GNU_STACK"; break;
    case PT_ARM_EXIDX: type = "EXIDX"; break;
    default: type = "(OTHER)"; break;
  }
  VLOG(1) << "phdr[" << program_header_index << "] : " << type;
  VLOG(1) << "  p_offset = " << program_header->p_offset;
  VLOG(1) << "  p_vaddr = " << program_header->p_vaddr;
  VLOG(1) << "  p_paddr = " << program_header->p_paddr;
  VLOG(1) << "  p_filesz = " << program_header->p_filesz;
  VLOG(1) << "  p_memsz = " << program_header->p_memsz;
  VLOG(1) << "  p_flags = " << program_header->p_flags;
  VLOG(1) << "  p_align = " << program_header->p_align;
}

// Verbose ELF section header logging.
void VerboseLogSectionHeader(const std::string& section_name,
                             const ELF::Shdr* section_header) {
  VLOG(1) << "section " << section_name;
  VLOG(1) << "  sh_addr = " << section_header->sh_addr;
  VLOG(1) << "  sh_offset = " << section_header->sh_offset;
  VLOG(1) << "  sh_size = " << section_header->sh_size;
  VLOG(1) << "  sh_addralign = " << section_header->sh_addralign;
}

// Verbose ELF section data logging.
void VerboseLogSectionData(const Elf_Data* data) {
  VLOG(1) << "  data";
  VLOG(1) << "    d_buf = " << data->d_buf;
  VLOG(1) << "    d_off = " << data->d_off;
  VLOG(1) << "    d_size = " << data->d_size;
  VLOG(1) << "    d_align = " << data->d_align;
}

}  // namespace

// Load the complete ELF file into a memory image in libelf, and identify
// the .rel.dyn or .rela.dyn, .dynamic, and .android.rel.dyn or
// .android.rela.dyn sections.  No-op if the ELF file has already been loaded.
bool ElfFile::Load() {
  if (elf_)
    return true;

  Elf* elf = elf_begin(fd_, ELF_C_RDWR, NULL);
  CHECK(elf);

  if (elf_kind(elf) != ELF_K_ELF) {
    LOG(ERROR) << "File not in ELF format";
    return false;
  }

  ELF::Ehdr* elf_header = ELF::getehdr(elf);
  if (!elf_header) {
    LOG(ERROR) << "Failed to load ELF header: " << elf_errmsg(elf_errno());
    return false;
  }
  if (elf_header->e_machine != ELF::kMachine) {
    LOG(ERROR) << "ELF file architecture is not " << ELF::Machine();
    return false;
  }
  if (elf_header->e_type != ET_DYN) {
    LOG(ERROR) << "ELF file is not a shared object";
    return false;
  }

  // Require that our endianness matches that of the target, and that both
  // are little-endian.  Safe for all current build/target combinations.
  const int endian = elf_header->e_ident[EI_DATA];
  CHECK(endian == ELFDATA2LSB);
  CHECK(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__);

  // Also require that the file class is as expected.
  const int file_class = elf_header->e_ident[EI_CLASS];
  CHECK(file_class == ELF::kFileClass);

  VLOG(1) << "endian = " << endian << ", file class = " << file_class;
  VerboseLogElfHeader(elf_header);

  const ELF::Phdr* elf_program_header = ELF::getphdr(elf);
  CHECK(elf_program_header);

  const ELF::Phdr* dynamic_program_header = NULL;
  for (size_t i = 0; i < elf_header->e_phnum; ++i) {
    const ELF::Phdr* program_header = &elf_program_header[i];
    VerboseLogProgramHeader(i, program_header);

    if (program_header->p_type == PT_DYNAMIC) {
      CHECK(dynamic_program_header == NULL);
      dynamic_program_header = program_header;
    }
  }
  CHECK(dynamic_program_header != NULL);

  size_t string_index;
  elf_getshdrstrndx(elf, &string_index);

  // Notes of the dynamic relocations, packed relocations, and .dynamic
  // sections.  Found while iterating sections, and later stored in class
  // attributes.
  Elf_Scn* found_relocations_section = NULL;
  Elf_Scn* found_android_relocations_section = NULL;
  Elf_Scn* found_dynamic_section = NULL;

  // Notes of relocation section types seen.  We require one or the other of
  // these; both is unsupported.
  bool has_rel_relocations = false;
  bool has_rela_relocations = false;

  Elf_Scn* section = NULL;
  while ((section = elf_nextscn(elf, section)) != NULL) {
    const ELF::Shdr* section_header = ELF::getshdr(section);
    std::string name = elf_strptr(elf, string_index, section_header->sh_name);
    VerboseLogSectionHeader(name, section_header);

    // Note relocation section types.
    if (section_header->sh_type == SHT_REL) {
      has_rel_relocations = true;
    }
    if (section_header->sh_type == SHT_RELA) {
      has_rela_relocations = true;
    }

    // Note special sections as we encounter them.
    if ((name == ".rel.dyn" || name == ".rela.dyn") &&
        section_header->sh_size > 0) {
      found_relocations_section = section;
    }
    if ((name == ".android.rel.dyn" || name == ".android.rela.dyn") &&
        section_header->sh_size > 0) {
      found_android_relocations_section = section;
    }
    if (section_header->sh_offset == dynamic_program_header->p_offset) {
      found_dynamic_section = section;
    }

    // Ensure we preserve alignment, repeated later for the data block(s).
    CHECK(section_header->sh_addralign <= kPreserveAlignment);

    Elf_Data* data = NULL;
    while ((data = elf_getdata(section, data)) != NULL) {
      CHECK(data->d_align <= kPreserveAlignment);
      VerboseLogSectionData(data);
    }
  }

  // Loading failed if we did not find the required special sections.
  if (!found_relocations_section) {
    LOG(ERROR) << "Missing or empty .rel.dyn or .rela.dyn section";
    return false;
  }
  if (!found_android_relocations_section) {
    LOG(ERROR) << "Missing or empty .android.rel.dyn or .android.rela.dyn "
               << "section (to fix, run with --help and follow the "
               << "pre-packing instructions)";
    return false;
  }
  if (!found_dynamic_section) {
    LOG(ERROR) << "Missing .dynamic section";
    return false;
  }

  // Loading failed if we could not identify the relocations type.
  if (!has_rel_relocations && !has_rela_relocations) {
    LOG(ERROR) << "No relocations sections found";
    return false;
  }
  if (has_rel_relocations && has_rela_relocations) {
    LOG(ERROR) << "Multiple relocations sections with different types found, "
               << "not currently supported";
    return false;
  }

  elf_ = elf;
  relocations_section_ = found_relocations_section;
  dynamic_section_ = found_dynamic_section;
  android_relocations_section_ = found_android_relocations_section;
  relocations_type_ = has_rel_relocations ? REL : RELA;
  return true;
}

namespace {

// Helper for ResizeSection().  Adjust the main ELF header for the hole.
void AdjustElfHeaderForHole(ELF::Ehdr* elf_header,
                            ELF::Off hole_start,
                            ssize_t hole_size) {
  if (elf_header->e_phoff > hole_start) {
    elf_header->e_phoff += hole_size;
    VLOG(1) << "e_phoff adjusted to " << elf_header->e_phoff;
  }
  if (elf_header->e_shoff > hole_start) {
    elf_header->e_shoff += hole_size;
    VLOG(1) << "e_shoff adjusted to " << elf_header->e_shoff;
  }
}

// Helper for ResizeSection().  Adjust all section headers for the hole.
void AdjustSectionHeadersForHole(Elf* elf,
                                 ELF::Off hole_start,
                                 ssize_t hole_size) {
  size_t string_index;
  elf_getshdrstrndx(elf, &string_index);

  Elf_Scn* section = NULL;
  while ((section = elf_nextscn(elf, section)) != NULL) {
    ELF::Shdr* section_header = ELF::getshdr(section);
    std::string name = elf_strptr(elf, string_index, section_header->sh_name);

    if (section_header->sh_offset > hole_start) {
      section_header->sh_offset += hole_size;
      VLOG(1) << "section " << name
              << " sh_offset adjusted to " << section_header->sh_offset;
    }
  }
}

// Helper for ResizeSection().  Adjust the offsets of any program headers
// that have offsets currently beyond the hole start.
void AdjustProgramHeaderOffsets(ELF::Phdr* program_headers,
                                size_t count,
                                ELF::Phdr* ignored_1,
                                ELF::Phdr* ignored_2,
                                ELF::Off hole_start,
                                ssize_t hole_size) {
  for (size_t i = 0; i < count; ++i) {
    ELF::Phdr* program_header = &program_headers[i];

    if (program_header == ignored_1 || program_header == ignored_2)
      continue;

    if (program_header->p_offset > hole_start) {
      // The hole start is past this segment, so adjust offset.
      program_header->p_offset += hole_size;
      VLOG(1) << "phdr[" << i
              << "] p_offset adjusted to "<< program_header->p_offset;
    }
  }
}

// Helper for ResizeSection().  Find the first loadable segment in the
// file.  We expect it to map from file offset zero.
ELF::Phdr* FindFirstLoadSegment(ELF::Phdr* program_headers,
                                size_t count) {
  ELF::Phdr* first_loadable_segment = NULL;

  for (size_t i = 0; i < count; ++i) {
    ELF::Phdr* program_header = &program_headers[i];

    if (program_header->p_type == PT_LOAD &&
        program_header->p_offset == 0 &&
        program_header->p_vaddr == 0 &&
        program_header->p_paddr == 0) {
      first_loadable_segment = program_header;
    }
  }
  LOG_IF(FATAL, !first_loadable_segment)
      << "Cannot locate a LOAD segment with address and offset zero";

  return first_loadable_segment;
}

// Helper for ResizeSection().  Find the PT_GNU_STACK segment, and check
// that it contains what we expect so we can restore it on unpack if needed.
ELF::Phdr* FindUnusedGnuStackSegment(ELF::Phdr* program_headers,
                                     size_t count) {
  ELF::Phdr* unused_segment = NULL;

  for (size_t i = 0; i < count; ++i) {
    ELF::Phdr* program_header = &program_headers[i];

    if (program_header->p_type == PT_GNU_STACK &&
        program_header->p_offset == 0 &&
        program_header->p_vaddr == 0 &&
        program_header->p_paddr == 0 &&
        program_header->p_filesz == 0 &&
        program_header->p_memsz == 0 &&
        program_header->p_flags == (PF_R | PF_W) &&
        program_header->p_align == ELF::kGnuStackSegmentAlignment) {
      unused_segment = program_header;
    }
  }
  LOG_IF(FATAL, !unused_segment)
      << "Cannot locate the expected GNU_STACK segment";

  return unused_segment;
}

// Helper for ResizeSection().  Find the segment that was the first loadable
// one before we split it into two.  This is the one into which we coalesce
// the split segments on unpacking.
ELF::Phdr* FindOriginalFirstLoadSegment(ELF::Phdr* program_headers,
                                        size_t count) {
  const ELF::Phdr* first_loadable_segment =
      FindFirstLoadSegment(program_headers, count);

  ELF::Phdr* original_first_loadable_segment = NULL;

  for (size_t i = 0; i < count; ++i) {
    ELF::Phdr* program_header = &program_headers[i];

    // The original first loadable segment is the one that follows on from
    // the one we wrote on split to be the current first loadable segment.
    if (program_header->p_type == PT_LOAD &&
        program_header->p_offset == first_loadable_segment->p_filesz) {
      original_first_loadable_segment = program_header;
    }
  }
  LOG_IF(FATAL, !original_first_loadable_segment)
      << "Cannot locate the LOAD segment that follows a LOAD at offset zero";

  return original_first_loadable_segment;
}

// Helper for ResizeSection().  Find the segment that contains the hole.
Elf_Scn* FindSectionContainingHole(Elf* elf,
                                   ELF::Off hole_start,
                                   ssize_t hole_size) {
  Elf_Scn* section = NULL;
  Elf_Scn* last_unholed_section = NULL;

  while ((section = elf_nextscn(elf, section)) != NULL) {
    const ELF::Shdr* section_header = ELF::getshdr(section);

    // Because we get here after section headers have been adjusted for the
    // hole, we need to 'undo' that adjustment to give a view of the original
    // sections layout.
    ELF::Off offset = section_header->sh_offset;
    if (section_header->sh_offset >= hole_start) {
      offset -= hole_size;
    }

    if (offset <= hole_start) {
      last_unholed_section = section;
    }
  }
  LOG_IF(FATAL, !last_unholed_section)
      << "Cannot identify the section before the one containing the hole";

  // The section containing the hole is the one after the last one found
  // by the loop above.
  Elf_Scn* holed_section = elf_nextscn(elf, last_unholed_section);
  LOG_IF(FATAL, !holed_section)
      << "Cannot identify the section containing the hole";

  return holed_section;
}

// Helper for ResizeSection().  Find the last section contained in a segment.
Elf_Scn* FindLastSectionInSegment(Elf* elf,
                                  ELF::Phdr* program_header,
                                  ELF::Off hole_start,
                                  ssize_t hole_size) {
  const ELF::Off segment_end =
      program_header->p_offset + program_header->p_filesz;

  Elf_Scn* section = NULL;
  Elf_Scn* last_section = NULL;

  while ((section = elf_nextscn(elf, section)) != NULL) {
    const ELF::Shdr* section_header = ELF::getshdr(section);

    // As above, 'undo' any section offset adjustment to give a view of the
    // original sections layout.
    ELF::Off offset = section_header->sh_offset;
    if (section_header->sh_offset >= hole_start) {
      offset -= hole_size;
    }

    if (offset < segment_end) {
      last_section = section;
    }
  }
  LOG_IF(FATAL, !last_section)
      << "Cannot identify the last section in the given segment";

  return last_section;
}

// Helper for ResizeSection().  Order loadable segments by their offsets.
// The crazy linker contains assumptions about loadable segment ordering,
// and it is better if we do not break them.
void SortOrderSensitiveProgramHeaders(ELF::Phdr* program_headers,
                                      size_t count) {
  std::vector<ELF::Phdr*> orderable;

  // Collect together orderable program headers.  These are all the LOAD
  // segments, and any GNU_STACK that may be present (removed on packing,
  // but replaced on unpacking).
  for (size_t i = 0; i < count; ++i) {
    ELF::Phdr* program_header = &program_headers[i];

    if (program_header->p_type == PT_LOAD ||
        program_header->p_type == PT_GNU_STACK) {
      orderable.push_back(program_header);
    }
  }

  // Order these program headers so that any PT_GNU_STACK is last, and
  // the LOAD segments that precede it appear in offset order.  Uses
  // insertion sort.
  for (size_t i = 1; i < orderable.size(); ++i) {
    for (size_t j = i; j > 0; --j) {
      ELF::Phdr* first = orderable[j - 1];
      ELF::Phdr* second = orderable[j];

      if (!(first->p_type == PT_GNU_STACK ||
            first->p_offset > second->p_offset)) {
        break;
      }
      std::swap(*first, *second);
    }
  }
}

// Helper for ResizeSection().  The GNU_STACK program header is unused in
// Android, so we can repurpose it here.  Before packing, the program header
// table contains something like:
//
//   Type      Offset    VirtAddr   PhysAddr   FileSiz   MemSiz    Flg Align
//   LOAD      0x000000  0x00000000 0x00000000 0x1efc818 0x1efc818 R E 0x1000
//   LOAD      0x1efd008 0x01efe008 0x01efe008 0x17ec3c  0x1a0324  RW  0x1000
//   DYNAMIC   0x205ec50 0x0205fc50 0x0205fc50 0x00108   0x00108   RW  0x4
//   GNU_STACK 0x000000  0x00000000 0x00000000 0x00000   0x00000   RW  0
//
// The hole in the file is in the first of these.  In order to preserve all
// load addresses, what we do is to turn the GNU_STACK into a new LOAD entry
// that maps segments up to where we created the hole, adjust the first LOAD
// entry so that it maps segments after that, adjust any other program
// headers whose offset is after the hole start, and finally order the LOAD
// segments by offset, to give:
//
//   Type      Offset    VirtAddr   PhysAddr   FileSiz   MemSiz    Flg Align
//   LOAD      0x000000  0x00000000 0x00000000 0x14ea4   0x14ea4   R E 0x1000
//   LOAD      0x014ea4  0x00212ea4 0x00212ea4 0x1cea164 0x1cea164 R E 0x1000
//   DYNAMIC   0x1e60c50 0x0205fc50 0x0205fc50 0x00108   0x00108   RW  0x4
//   LOAD      0x1cff008 0x01efe008 0x01efe008 0x17ec3c  0x1a0324  RW  0x1000
//
// We work out the split points by finding the .rel.dyn or .rela.dyn section
// that contains the hole, and by finding the last section in a given segment.
//
// To unpack, we reverse the above to leave the file as it was originally.
void SplitProgramHeadersForHole(Elf* elf,
                                ELF::Off hole_start,
                                ssize_t hole_size) {
  CHECK(hole_size < 0);
  const ELF::Ehdr* elf_header = ELF::getehdr(elf);
  CHECK(elf_header);

  ELF::Phdr* elf_program_header = ELF::getphdr(elf);
  CHECK(elf_program_header);

  const size_t program_header_count = elf_header->e_phnum;

  // Locate the segment that we can overwrite to form the new LOAD entry,
  // and the segment that we are going to split into two parts.
  ELF::Phdr* spliced_header =
      FindUnusedGnuStackSegment(elf_program_header, program_header_count);
  ELF::Phdr* split_header =
      FindFirstLoadSegment(elf_program_header, program_header_count);

  VLOG(1) << "phdr[" << split_header - elf_program_header << "] split";
  VLOG(1) << "phdr[" << spliced_header - elf_program_header << "] new LOAD";

  // Find the section that contains the hole.  We split on the section that
  // follows it.
  Elf_Scn* holed_section =
      FindSectionContainingHole(elf, hole_start, hole_size);

  size_t string_index;
  elf_getshdrstrndx(elf, &string_index);

  ELF::Shdr* section_header = ELF::getshdr(holed_section);
  std::string name = elf_strptr(elf, string_index, section_header->sh_name);
  VLOG(1) << "section " << name << " split after";

  // Find the last section in the segment we are splitting.
  Elf_Scn* last_section =
      FindLastSectionInSegment(elf, split_header, hole_start, hole_size);

  section_header = ELF::getshdr(last_section);
  name = elf_strptr(elf, string_index, section_header->sh_name);
  VLOG(1) << "section " << name << " split end";

  // Split on the section following the holed one, and up to (but not
  // including) the section following the last one in the split segment.
  Elf_Scn* split_section = elf_nextscn(elf, holed_section);
  LOG_IF(FATAL, !split_section)
      << "No section follows the section that contains the hole";
  Elf_Scn* end_section = elf_nextscn(elf, last_section);
  LOG_IF(FATAL, !end_section)
      << "No section follows the last section in the segment being split";

  // Split the first portion of split_header into spliced_header.
  const ELF::Shdr* split_section_header = ELF::getshdr(split_section);
  spliced_header->p_type = split_header->p_type;
  spliced_header->p_offset = split_header->p_offset;
  spliced_header->p_vaddr = split_header->p_vaddr;
  spliced_header->p_paddr = split_header->p_paddr;
  CHECK(split_header->p_filesz == split_header->p_memsz);
  spliced_header->p_filesz = split_section_header->sh_offset;
  spliced_header->p_memsz = split_section_header->sh_offset;
  spliced_header->p_flags = split_header->p_flags;
  spliced_header->p_align = split_header->p_align;

  // Now rewrite split_header to remove the part we spliced from it.
  const ELF::Shdr* end_section_header = ELF::getshdr(end_section);
  split_header->p_offset = spliced_header->p_filesz;
  CHECK(split_header->p_vaddr == split_header->p_paddr);
  split_header->p_vaddr = split_section_header->sh_addr;
  split_header->p_paddr = split_section_header->sh_addr;
  CHECK(split_header->p_filesz == split_header->p_memsz);
  split_header->p_filesz =
      end_section_header->sh_offset - spliced_header->p_filesz;
  split_header->p_memsz =
      end_section_header->sh_offset - spliced_header->p_filesz;

  // Adjust the offsets of all program headers that are not one of the pair
  // we just created by splitting.
  AdjustProgramHeaderOffsets(elf_program_header,
                             program_header_count,
                             spliced_header,
                             split_header,
                             hole_start,
                             hole_size);

  // Finally, order loadable segments by offset/address.  The crazy linker
  // contains assumptions about loadable segment ordering.
  SortOrderSensitiveProgramHeaders(elf_program_header,
                                   program_header_count);
}

// Helper for ResizeSection().  Undo the work of SplitProgramHeadersForHole().
void CoalesceProgramHeadersForHole(Elf* elf,
                                   ELF::Off hole_start,
                                   ssize_t hole_size) {
  CHECK(hole_size > 0);
  const ELF::Ehdr* elf_header = ELF::getehdr(elf);
  CHECK(elf_header);

  ELF::Phdr* elf_program_header = ELF::getphdr(elf);
  CHECK(elf_program_header);

  const size_t program_header_count = elf_header->e_phnum;

  // Locate the segment that we overwrote to form the new LOAD entry, and
  // the segment that we split into two parts on packing.
  ELF::Phdr* spliced_header =
      FindFirstLoadSegment(elf_program_header, program_header_count);
  ELF::Phdr* split_header =
      FindOriginalFirstLoadSegment(elf_program_header, program_header_count);

  VLOG(1) << "phdr[" << spliced_header - elf_program_header << "] stack";
  VLOG(1) << "phdr[" << split_header - elf_program_header << "] coalesce";

  // Find the last section in the second segment we are coalescing.
  Elf_Scn* last_section =
      FindLastSectionInSegment(elf, split_header, hole_start, hole_size);

  size_t string_index;
  elf_getshdrstrndx(elf, &string_index);

  const ELF::Shdr* section_header = ELF::getshdr(last_section);
  std::string name = elf_strptr(elf, string_index, section_header->sh_name);
  VLOG(1) << "section " << name << " coalesced";

  // Rewrite the coalesced segment into split_header.
  const ELF::Shdr* last_section_header = ELF::getshdr(last_section);
  split_header->p_offset = spliced_header->p_offset;
  CHECK(split_header->p_vaddr == split_header->p_paddr);
  split_header->p_vaddr = spliced_header->p_vaddr;
  split_header->p_paddr = spliced_header->p_vaddr;
  CHECK(split_header->p_filesz == split_header->p_memsz);
  split_header->p_filesz =
      last_section_header->sh_offset + last_section_header->sh_size;
  split_header->p_memsz =
      last_section_header->sh_offset + last_section_header->sh_size;

  // Reconstruct the original GNU_STACK segment into spliced_header.
  spliced_header->p_type = PT_GNU_STACK;
  spliced_header->p_offset = 0;
  spliced_header->p_vaddr = 0;
  spliced_header->p_paddr = 0;
  spliced_header->p_filesz = 0;
  spliced_header->p_memsz = 0;
  spliced_header->p_flags = PF_R | PF_W;
  spliced_header->p_align = ELF::kGnuStackSegmentAlignment;

  // Adjust the offsets of all program headers that are not one of the pair
  // we just coalesced.
  AdjustProgramHeaderOffsets(elf_program_header,
                             program_header_count,
                             spliced_header,
                             split_header,
                             hole_start,
                             hole_size);

  // Finally, order loadable segments by offset/address.  The crazy linker
  // contains assumptions about loadable segment ordering.
  SortOrderSensitiveProgramHeaders(elf_program_header,
                                   program_header_count);
}

// Helper for ResizeSection().  Rewrite program headers.
void RewriteProgramHeadersForHole(Elf* elf,
                                  ELF::Off hole_start,
                                  ssize_t hole_size) {
  // If hole_size is negative then we are removing a piece of the file, and
  // we want to split program headers so that we keep the same addresses
  // for text and data.  If positive, then we are putting that piece of the
  // file back in, so we coalesce the previously split program headers.
  if (hole_size < 0)
    SplitProgramHeadersForHole(elf, hole_start, hole_size);
  else if (hole_size > 0)
    CoalesceProgramHeadersForHole(elf, hole_start, hole_size);
}

// Helper for ResizeSection().  Locate and return the dynamic section.
Elf_Scn* GetDynamicSection(Elf* elf) {
  const ELF::Ehdr* elf_header = ELF::getehdr(elf);
  CHECK(elf_header);

  const ELF::Phdr* elf_program_header = ELF::getphdr(elf);
  CHECK(elf_program_header);

  // Find the program header that describes the dynamic section.
  const ELF::Phdr* dynamic_program_header = NULL;
  for (size_t i = 0; i < elf_header->e_phnum; ++i) {
    const ELF::Phdr* program_header = &elf_program_header[i];

    if (program_header->p_type == PT_DYNAMIC) {
      dynamic_program_header = program_header;
    }
  }
  CHECK(dynamic_program_header);

  // Now find the section with the same offset as this program header.
  Elf_Scn* dynamic_section = NULL;
  Elf_Scn* section = NULL;
  while ((section = elf_nextscn(elf, section)) != NULL) {
    ELF::Shdr* section_header = ELF::getshdr(section);

    if (section_header->sh_offset == dynamic_program_header->p_offset) {
      dynamic_section = section;
    }
  }
  CHECK(dynamic_section != NULL);

  return dynamic_section;
}

// Helper for ResizeSection().  Adjust the .dynamic section for the hole.
template <typename Rel>
void AdjustDynamicSectionForHole(Elf_Scn* dynamic_section,
                                 ELF::Off hole_start,
                                 ssize_t hole_size) {
  Elf_Data* data = GetSectionData(dynamic_section);

  const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
  std::vector<ELF::Dyn> dynamics(
      dynamic_base,
      dynamic_base + data->d_size / sizeof(dynamics[0]));

  for (size_t i = 0; i < dynamics.size(); ++i) {
    ELF::Dyn* dynamic = &dynamics[i];
    const ELF::Sword tag = dynamic->d_tag;

    // DT_RELSZ or DT_RELASZ indicate the overall size of relocations.
    // Only one will be present.  Adjust by hole size.
    if (tag == DT_RELSZ || tag == DT_RELASZ) {
      dynamic->d_un.d_val += hole_size;
      VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
              << " d_val adjusted to " << dynamic->d_un.d_val;
    }

    // DT_RELCOUNT or DT_RELACOUNT hold the count of relative relocations.
    // Only one will be present.  Packing reduces it to the alignment
    // padding, if any; unpacking restores it to its former value.  The
    // crazy linker does not use it, but we update it anyway.
    if (tag == DT_RELCOUNT || tag == DT_RELACOUNT) {
      // Cast sizeof to a signed type to avoid the division result being
      // promoted into an unsigned size_t.
      const ssize_t sizeof_rel = static_cast<ssize_t>(sizeof(Rel));
      dynamic->d_un.d_val += hole_size / sizeof_rel;
      VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
              << " d_val adjusted to " << dynamic->d_un.d_val;
    }

    // DT_RELENT and DT_RELAENT do not change, but make sure they are what
    // we expect.  Only one will be present.
    if (tag == DT_RELENT || tag == DT_RELAENT) {
      CHECK(dynamic->d_un.d_val == sizeof(Rel));
    }
  }

  void* section_data = &dynamics[0];
  size_t bytes = dynamics.size() * sizeof(dynamics[0]);
  RewriteSectionData(data, section_data, bytes);
}

// Resize a section.  If the new size is larger than the current size, open
// up a hole by increasing file offsets that come after the hole.  If smaller
// than the current size, remove the hole by decreasing those offsets.
template <typename Rel>
void ResizeSection(Elf* elf, Elf_Scn* section, size_t new_size) {
  ELF::Shdr* section_header = ELF::getshdr(section);
  if (section_header->sh_size == new_size)
    return;

  // Note if we are resizing the real dyn relocations.
  size_t string_index;
  elf_getshdrstrndx(elf, &string_index);
  const std::string section_name =
      elf_strptr(elf, string_index, section_header->sh_name);
  const bool is_relocations_resize =
      (section_name == ".rel.dyn" || section_name == ".rela.dyn");

  // Require that the section size and the data size are the same.  True
  // in practice for all sections we resize when packing or unpacking.
  Elf_Data* data = GetSectionData(section);
  CHECK(data->d_off == 0 && data->d_size == section_header->sh_size);

  // Require that the section is not zero-length (that is, has allocated
  // data that we can validly expand).
  CHECK(data->d_size && data->d_buf);

  const ELF::Off hole_start = section_header->sh_offset;
  const ssize_t hole_size = new_size - data->d_size;

  VLOG_IF(1, (hole_size > 0)) << "expand section size = " << data->d_size;
  VLOG_IF(1, (hole_size < 0)) << "shrink section size = " << data->d_size;

  // Resize the data and the section header.
  data->d_size += hole_size;
  section_header->sh_size += hole_size;

  // Add the hole size to all offsets in the ELF file that are after the
  // start of the hole.  If the hole size is positive we are expanding the
  // section to create a new hole; if negative, we are closing up a hole.

  // Start with the main ELF header.
  ELF::Ehdr* elf_header = ELF::getehdr(elf);
  AdjustElfHeaderForHole(elf_header, hole_start, hole_size);

  // Adjust all section headers.
  AdjustSectionHeadersForHole(elf, hole_start, hole_size);

  // If resizing the dynamic relocations, rewrite the program headers to
  // either split or coalesce segments, and adjust dynamic entries to match.
  if (is_relocations_resize) {
    RewriteProgramHeadersForHole(elf, hole_start, hole_size);

    Elf_Scn* dynamic_section = GetDynamicSection(elf);
    AdjustDynamicSectionForHole<Rel>(dynamic_section, hole_start, hole_size);
  }
}

// Find the first slot in a dynamics array with the given tag.  The array
// always ends with a free (unused) element, and which we exclude from the
// search.  Returns dynamics->size() if not found.
size_t FindDynamicEntry(ELF::Sword tag,
                        std::vector<ELF::Dyn>* dynamics) {
  // Loop until the penultimate entry.  We exclude the end sentinel.
  for (size_t i = 0; i < dynamics->size() - 1; ++i) {
    if (dynamics->at(i).d_tag == tag)
      return i;
  }

  // The tag was not found.
  return dynamics->size();
}

// Replace the first free (unused) slot in a dynamics vector with the given
// value.  The vector always ends with a free (unused) element, so the slot
// found cannot be the last one in the vector.
void AddDynamicEntry(const ELF::Dyn& dyn,
                     std::vector<ELF::Dyn>* dynamics) {
  const size_t slot = FindDynamicEntry(DT_NULL, dynamics);
  if (slot == dynamics->size()) {
    LOG(FATAL) << "No spare dynamic array slots found "
               << "(to fix, increase gold's --spare-dynamic-tags value)";
  }

  // Replace this entry with the one supplied.
  dynamics->at(slot) = dyn;
  VLOG(1) << "dynamic[" << slot << "] overwritten with " << dyn.d_tag;
}

// Remove the element in the dynamics vector that matches the given tag with
// unused slot data.  Shuffle the following elements up, and ensure that the
// last is the null sentinel.
void RemoveDynamicEntry(ELF::Sword tag,
                        std::vector<ELF::Dyn>* dynamics) {
  const size_t slot = FindDynamicEntry(tag, dynamics);
  CHECK(slot != dynamics->size());

  // Remove this entry by shuffling up everything that follows.
  for (size_t i = slot; i < dynamics->size() - 1; ++i) {
    dynamics->at(i) = dynamics->at(i + 1);
    VLOG(1) << "dynamic[" << i
            << "] overwritten with dynamic[" << i + 1 << "]";
  }

  // Ensure that the end sentinel is still present.
  CHECK(dynamics->at(dynamics->size() - 1).d_tag == DT_NULL);
}

// Construct a null relocation without addend.
void NullRelocation(ELF::Rel* relocation) {
  relocation->r_offset = 0;
  relocation->r_info = ELF_R_INFO(0, ELF::kNoRelocationCode);
}

// Construct a null relocation with addend.
void NullRelocation(ELF::Rela* relocation) {
  relocation->r_offset = 0;
  relocation->r_info = ELF_R_INFO(0, ELF::kNoRelocationCode);
  relocation->r_addend = 0;
}

// Pad relocations with the given number of null entries.  Generates its
// null entry with the appropriate NullRelocation() invocation.
template <typename Rel>
void PadRelocations(size_t count, std::vector<Rel>* relocations) {
  Rel null_relocation;
  NullRelocation(&null_relocation);
  std::vector<Rel> padding(count, null_relocation);
  relocations->insert(relocations->end(), padding.begin(), padding.end());
}

}  // namespace

// Remove relative entries from dynamic relocations and write as packed
// data into android packed relocations.
bool ElfFile::PackRelocations() {
  // Load the ELF file into libelf.
  if (!Load()) {
    LOG(ERROR) << "Failed to load as ELF";
    return false;
  }

  // Retrieve the current dynamic relocations section data.
  Elf_Data* data = GetSectionData(relocations_section_);

  if (relocations_type_ == REL) {
    // Convert data to a vector of relocations.
    const ELF::Rel* relocations_base = reinterpret_cast<ELF::Rel*>(data->d_buf);
    std::vector<ELF::Rel> relocations(
        relocations_base,
        relocations_base + data->d_size / sizeof(relocations[0]));

    LOG(INFO) << "Relocations   : REL";
    return PackTypedRelocations<ELF::Rel>(relocations, data);
  }

  if (relocations_type_ == RELA) {
    // Convert data to a vector of relocations with addends.
    const ELF::Rela* relocations_base =
        reinterpret_cast<ELF::Rela*>(data->d_buf);
    std::vector<ELF::Rela> relocations(
        relocations_base,
        relocations_base + data->d_size / sizeof(relocations[0]));

    LOG(INFO) << "Relocations   : RELA";
    return PackTypedRelocations<ELF::Rela>(relocations, data);
  }

  NOTREACHED();
  return false;
}

// Helper for PackRelocations().  Rel type is one of ELF::Rel or ELF::Rela.
template <typename Rel>
bool ElfFile::PackTypedRelocations(const std::vector<Rel>& relocations,
                                   Elf_Data* data) {
  // Filter relocations into those that are relative and others.
  std::vector<Rel> relative_relocations;
  std::vector<Rel> other_relocations;

  for (size_t i = 0; i < relocations.size(); ++i) {
    const Rel& relocation = relocations[i];
    if (ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode) {
      CHECK(ELF_R_SYM(relocation.r_info) == 0);
      relative_relocations.push_back(relocation);
    } else {
      other_relocations.push_back(relocation);
    }
  }
  LOG(INFO) << "Relative      : " << relative_relocations.size() << " entries";
  LOG(INFO) << "Other         : " << other_relocations.size() << " entries";
  LOG(INFO) << "Total         : " << relocations.size() << " entries";

  // If no relative relocations then we have nothing packable.  Perhaps
  // the shared object has already been packed?
  if (relative_relocations.empty()) {
    LOG(ERROR) << "No relative relocations found (already packed?)";
    return false;
  }

  // If not padding fully, apply only enough padding to preserve alignment.
  // Otherwise, pad so that we do not shrink the relocations section at all.
  if (!is_padding_relocations_) {
    // Calculate the size of the hole we will close up when we rewrite
    // dynamic relocations.
    ssize_t hole_size =
        relative_relocations.size() * sizeof(relative_relocations[0]);
    const ssize_t unaligned_hole_size = hole_size;

    // Adjust the actual hole size to preserve alignment.  We always adjust
    // by a whole number of NONE-type relocations.
    while (hole_size % kPreserveAlignment)
      hole_size -= sizeof(relative_relocations[0]);
    LOG(INFO) << "Compaction    : " << hole_size << " bytes";

    // Adjusting for alignment may have removed any packing benefit.
    if (hole_size == 0) {
      LOG(INFO) << "Too few relative relocations to pack after alignment";
      return false;
    }

    // Find the padding needed in other_relocations to preserve alignment.
    // Ensure that we never completely empty the real relocations section.
    size_t padding_bytes = unaligned_hole_size - hole_size;
    if (padding_bytes == 0 && other_relocations.size() == 0) {
      do {
        padding_bytes += sizeof(relative_relocations[0]);
      } while (padding_bytes % kPreserveAlignment);
    }
    CHECK(padding_bytes % sizeof(other_relocations[0]) == 0);
    const size_t padding = padding_bytes / sizeof(other_relocations[0]);

    // Padding may have removed any packing benefit.
    if (padding >= relative_relocations.size()) {
      LOG(INFO) << "Too few relative relocations to pack after padding";
      return false;
    }

    // Add null relocations to other_relocations to preserve alignment.
    PadRelocations<Rel>(padding, &other_relocations);
    LOG(INFO) << "Alignment pad : " << padding << " relocations";
  } else {
    // If padding, add NONE-type relocations to other_relocations to make it
    // the same size as the the original relocations we read in.  This makes
    // the ResizeSection() below a no-op.
    const size_t padding = relocations.size() - other_relocations.size();
    PadRelocations<Rel>(padding, &other_relocations);
  }

  // Pack relative relocations.
  const size_t initial_bytes =
      relative_relocations.size() * sizeof(relative_relocations[0]);
  LOG(INFO) << "Unpacked relative: " << initial_bytes << " bytes";
  std::vector<uint8_t> packed;
  RelocationPacker packer;
  packer.PackRelativeRelocations(relative_relocations, &packed);
  const void* packed_data = &packed[0];
  const size_t packed_bytes = packed.size() * sizeof(packed[0]);
  LOG(INFO) << "Packed   relative: " << packed_bytes << " bytes";

  // If we have insufficient relative relocations to form a run then
  // packing fails.
  if (packed.empty()) {
    LOG(INFO) << "Too few relative relocations to pack";
    return false;
  }

  // Run a loopback self-test as a check that packing is lossless.
  std::vector<Rel> unpacked;
  packer.UnpackRelativeRelocations(packed, &unpacked);
  CHECK(unpacked.size() == relative_relocations.size());
  CHECK(!memcmp(&unpacked[0],
                &relative_relocations[0],
                unpacked.size() * sizeof(unpacked[0])));

  // Make sure packing saved some space.
  if (packed_bytes >= initial_bytes) {
    LOG(INFO) << "Packing relative relocations saves no space";
    return false;
  }

  // Rewrite the current dynamic relocations section to be only the ARM
  // non-relative relocations, then shrink it to size.
  const void* section_data = &other_relocations[0];
  const size_t bytes = other_relocations.size() * sizeof(other_relocations[0]);
  ResizeSection<Rel>(elf_, relocations_section_, bytes);
  RewriteSectionData(data, section_data, bytes);

  // Rewrite the current packed android relocations section to hold the packed
  // relative relocations.
  data = GetSectionData(android_relocations_section_);
  ResizeSection<Rel>(elf_, android_relocations_section_, packed_bytes);
  RewriteSectionData(data, packed_data, packed_bytes);

  // Rewrite .dynamic to include two new tags describing the packed android
  // relocations.
  data = GetSectionData(dynamic_section_);
  const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
  std::vector<ELF::Dyn> dynamics(
      dynamic_base,
      dynamic_base + data->d_size / sizeof(dynamics[0]));
  // Use two of the spare slots to describe the packed section.
  ELF::Shdr* section_header = ELF::getshdr(android_relocations_section_);
  {
    ELF::Dyn dyn;
    dyn.d_tag = DT_ANDROID_REL_OFFSET;
    dyn.d_un.d_ptr = section_header->sh_offset;
    AddDynamicEntry(dyn, &dynamics);
  }
  {
    ELF::Dyn dyn;
    dyn.d_tag = DT_ANDROID_REL_SIZE;
    dyn.d_un.d_val = section_header->sh_size;
    AddDynamicEntry(dyn, &dynamics);
  }
  const void* dynamics_data = &dynamics[0];
  const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
  RewriteSectionData(data, dynamics_data, dynamics_bytes);

  Flush();
  return true;
}

// Find packed relative relocations in the packed android relocations
// section, unpack them, and rewrite the dynamic relocations section to
// contain unpacked data.
bool ElfFile::UnpackRelocations() {
  // Load the ELF file into libelf.
  if (!Load()) {
    LOG(ERROR) << "Failed to load as ELF";
    return false;
  }

  // Retrieve the current packed android relocations section data.
  Elf_Data* data = GetSectionData(android_relocations_section_);

  // Convert data to a vector of bytes.
  const uint8_t* packed_base = reinterpret_cast<uint8_t*>(data->d_buf);
  std::vector<uint8_t> packed(
      packed_base,
      packed_base + data->d_size / sizeof(packed[0]));

  if (packed.size() > 3 &&
      packed[0] == 'A' &&
      packed[1] == 'P' &&
      packed[2] == 'R' &&
      packed[3] == '1') {
    // Signature is APR1, unpack relocations.
    CHECK(relocations_type_ == REL);
    LOG(INFO) << "Relocations   : REL";
    return UnpackTypedRelocations<ELF::Rel>(packed, data);
  }

  if (packed.size() > 3 &&
      packed[0] == 'A' &&
      packed[1] == 'P' &&
      packed[2] == 'A' &&
      packed[3] == '1') {
    // Signature is APA1, unpack relocations with addends.
    CHECK(relocations_type_ == RELA);
    LOG(INFO) << "Relocations   : RELA";
    return UnpackTypedRelocations<ELF::Rela>(packed, data);
  }

  LOG(ERROR) << "Packed relative relocations not found (not packed?)";
  return false;
}

// Helper for UnpackRelocations().  Rel type is one of ELF::Rel or ELF::Rela.
template <typename Rel>
bool ElfFile::UnpackTypedRelocations(const std::vector<uint8_t>& packed,
                                     Elf_Data* data) {
  // Unpack the data to re-materialize the relative relocations.
  const size_t packed_bytes = packed.size() * sizeof(packed[0]);
  LOG(INFO) << "Packed   relative: " << packed_bytes << " bytes";
  std::vector<Rel> relative_relocations;
  RelocationPacker packer;
  packer.UnpackRelativeRelocations(packed, &relative_relocations);
  const size_t unpacked_bytes =
      relative_relocations.size() * sizeof(relative_relocations[0]);
  LOG(INFO) << "Unpacked relative: " << unpacked_bytes << " bytes";

  // Retrieve the current dynamic relocations section data.
  data = GetSectionData(relocations_section_);

  // Interpret data as relocations.
  const Rel* relocations_base = reinterpret_cast<Rel*>(data->d_buf);
  std::vector<Rel> relocations(
      relocations_base,
      relocations_base + data->d_size / sizeof(relocations[0]));

  std::vector<Rel> other_relocations;
  size_t padding = 0;

  // Filter relocations to locate any that are NONE-type.  These will occur
  // if padding was turned on for packing.
  for (size_t i = 0; i < relocations.size(); ++i) {
    const Rel& relocation = relocations[i];
    if (ELF_R_TYPE(relocation.r_info) != ELF::kNoRelocationCode) {
      other_relocations.push_back(relocation);
    } else {
      ++padding;
    }
  }
  LOG(INFO) << "Relative      : " << relative_relocations.size() << " entries";
  LOG(INFO) << "Other         : " << other_relocations.size() << " entries";

  // If we found the same number of null relocation entries in the dynamic
  // relocations section as we hold as unpacked relative relocations, then
  // this is a padded file.
  const bool is_padded = padding == relative_relocations.size();

  // Unless padded, report by how much we expand the file.
  if (!is_padded) {
    // Calculate the size of the hole we will open up when we rewrite
    // dynamic relocations.
    ssize_t hole_size =
        relative_relocations.size() * sizeof(relative_relocations[0]);

    // Adjust the hole size for the padding added to preserve alignment.
    hole_size -= padding * sizeof(other_relocations[0]);
    LOG(INFO) << "Expansion     : " << hole_size << " bytes";
  }

  // Rewrite the current dynamic relocations section to be the relative
  // relocations followed by other relocations.  This is the usual order in
  // which we find them after linking, so this action will normally put the
  // entire dynamic relocations section back to its pre-split-and-packed state.
  relocations.assign(relative_relocations.begin(), relative_relocations.end());
  relocations.insert(relocations.end(),
                     other_relocations.begin(), other_relocations.end());
  const void* section_data = &relocations[0];
  const size_t bytes = relocations.size() * sizeof(relocations[0]);
  LOG(INFO) << "Total         : " << relocations.size() << " entries";
  ResizeSection<Rel>(elf_, relocations_section_, bytes);
  RewriteSectionData(data, section_data, bytes);

  // Nearly empty the current packed android relocations section.  Leaves a
  // four-byte stub so that some data remains allocated to the section.
  // This is a convenience which allows us to re-pack this file again without
  // having to remove the section and then add a new small one with objcopy.
  // The way we resize sections relies on there being some data in a section.
  data = GetSectionData(android_relocations_section_);
  ResizeSection<Rel>(
      elf_, android_relocations_section_, sizeof(kStubIdentifier));
  RewriteSectionData(data, &kStubIdentifier, sizeof(kStubIdentifier));

  // Rewrite .dynamic to remove two tags describing packed android relocations.
  data = GetSectionData(dynamic_section_);
  const ELF::Dyn* dynamic_base = reinterpret_cast<ELF::Dyn*>(data->d_buf);
  std::vector<ELF::Dyn> dynamics(
      dynamic_base,
      dynamic_base + data->d_size / sizeof(dynamics[0]));
  RemoveDynamicEntry(DT_ANDROID_REL_OFFSET, &dynamics);
  RemoveDynamicEntry(DT_ANDROID_REL_SIZE, &dynamics);
  const void* dynamics_data = &dynamics[0];
  const size_t dynamics_bytes = dynamics.size() * sizeof(dynamics[0]);
  RewriteSectionData(data, dynamics_data, dynamics_bytes);

  Flush();
  return true;
}

// Flush rewritten shared object file data.
void ElfFile::Flush() {
  // Flag all ELF data held in memory as needing to be written back to the
  // file, and tell libelf that we have controlled the file layout.
  elf_flagelf(elf_, ELF_C_SET, ELF_F_DIRTY);
  elf_flagelf(elf_, ELF_C_SET, ELF_F_LAYOUT);

  // Write ELF data back to disk.
  const off_t file_bytes = elf_update(elf_, ELF_C_WRITE);
  CHECK(file_bytes > 0);
  VLOG(1) << "elf_update returned: " << file_bytes;

  // Clean up libelf, and truncate the output file to the number of bytes
  // written by elf_update().
  elf_end(elf_);
  elf_ = NULL;
  const int truncate = ftruncate(fd_, file_bytes);
  CHECK(truncate == 0);
}

}  // namespace relocation_packer
