// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "courgette/disassembler_win32.h"

#include <algorithm>

#include "base/functional/bind.h"
#include "base/logging.h"
#include "courgette/assembly_program.h"
#include "courgette/courgette.h"

#if COURGETTE_HISTOGRAM_TARGETS
#include <iostream>
#endif

namespace courgette {

DisassemblerWin32::DisassemblerWin32(const uint8_t* start, size_t length)
    : Disassembler(start, length) {}

RVA DisassemblerWin32::FileOffsetToRVA(FileOffset file_offset) const {
  for (int i = 0; i < number_of_sections_; ++i) {
    const Section* section = &sections_[i];
    if (file_offset >= section->file_offset_of_raw_data) {
      FileOffset offset_in_section =
          file_offset - section->file_offset_of_raw_data;
      if (offset_in_section < section->size_of_raw_data)
        return static_cast<RVA>(section->virtual_address + offset_in_section);
    }
  }

  NOTREACHED();
  return kNoRVA;
}

FileOffset DisassemblerWin32::RVAToFileOffset(RVA rva) const {
  const Section* section = RVAToSection(rva);
  if (section != nullptr) {
    FileOffset offset_in_section = rva - section->virtual_address;
    // Need this extra check, since an |rva| may be valid for a section, but is
    // non-existent in an image (e.g. uninit data).
    if (offset_in_section >= section->size_of_raw_data)
      return kNoFileOffset;

    return static_cast<FileOffset>(section->file_offset_of_raw_data +
                                   offset_in_section);
  }

  // Small RVA values point into the file header in the loaded image.
  // RVA 0 is the module load address which Windows uses as the module handle.
  // RVA 2 sometimes occurs, I'm not sure what it is, but it would map into the
  // DOS header.
  if (rva == 0 || rva == 2)
    return static_cast<FileOffset>(rva);

  NOTREACHED();
  return kNoFileOffset;
}

// ParseHeader attempts to match up the buffer with the Windows data
// structures that exist within a Windows 'Portable Executable' format file.
// Returns 'true' if the buffer matches, and 'false' if the data looks
// suspicious.  Rather than try to 'map' the buffer to the numerous windows
// structures, we extract the information we need into the courgette::PEInfo
// structure.
//
bool DisassemblerWin32::ParseHeader() {
  if (!IsRangeInBounds(kOffsetOfFileAddressOfNewExeHeader, 4))
    return Bad("Too small");

  // Have 'MZ' magic for a DOS header?
  if (start()[0] != 'M' || start()[1] != 'Z')
    return Bad("Not MZ");

  // offset from DOS header to PE header is stored in DOS header.
  FileOffset pe_header_offset = static_cast<FileOffset>(
      ReadU32(start(), kOffsetOfFileAddressOfNewExeHeader));
  if (pe_header_offset % 8 != 0)
    return Bad("Misaligned PE header");
  if (pe_header_offset < kOffsetOfFileAddressOfNewExeHeader + 4)
    return Bad("PE header pathological overlap");
  if (!IsRangeInBounds(pe_header_offset, kMinPeHeaderSize))
    return Bad("PE header past end of file");

  const uint8_t* const pe_header = FileOffsetToPointer(pe_header_offset);

  // The 'PE' header is an IMAGE_NT_HEADERS structure as defined in WINNT.H.
  // See http://msdn.microsoft.com/en-us/library/ms680336(VS.85).aspx
  //
  // The first field of the IMAGE_NT_HEADERS is the signature.
  if (!(pe_header[0] == 'P' && pe_header[1] == 'E' && pe_header[2] == 0 &&
        pe_header[3] == 0)) {
    return Bad("No PE signature");
  }

  // The second field of the IMAGE_NT_HEADERS is the COFF header.
  // The COFF header is also called an IMAGE_FILE_HEADER
  //   http://msdn.microsoft.com/en-us/library/ms680313(VS.85).aspx
  FileOffset coff_header_offset = pe_header_offset + 4;
  if (!IsRangeInBounds(coff_header_offset, kSizeOfCoffHeader))
    return Bad("COFF header past end of file");
  const uint8_t* const coff_header = start() + coff_header_offset;
  machine_type_ = ReadU16(coff_header, 0);
  number_of_sections_ = ReadU16(coff_header, 2);
  size_of_optional_header_ = ReadU16(coff_header, 16);
  // Check we can read the magic.
  if (size_of_optional_header_ < 2)
    return Bad("Optional header no magic");
  // Check that we can read the rest of the the fixed fields. Data directories
  // directly follow the fixed fields of the IMAGE_OPTIONAL_HEADER.
  if (size_of_optional_header_ < RelativeOffsetOfDataDirectories())
    return Bad("Optional header too short");

  // The rest of the IMAGE_NT_HEADERS is the IMAGE_OPTIONAL_HEADER(32|64)
  FileOffset optional_header_offset = pe_header_offset + kMinPeHeaderSize;
  if (!IsRangeInBounds(optional_header_offset, size_of_optional_header_))
    return Bad("Optional header past end of file");
  optional_header_ = start() + optional_header_offset;

  uint16_t magic = ReadU16(optional_header_, 0);
  switch (kind()) {
    case EXE_WIN_32_X86:
      if (magic != kImageNtOptionalHdr32Magic)
        return Bad("64 bit executables are not supported by this disassembler");
      break;

    case EXE_WIN_32_X64:
      if (magic != kImageNtOptionalHdr64Magic)
        return Bad("32 bit executables are not supported by this disassembler");
      break;

    default:
      return Bad("Unrecognized magic");
  }

  // The optional header is either an IMAGE_OPTIONAL_HEADER32 or
  // IMAGE_OPTIONAL_HEADER64
  // http://msdn.microsoft.com/en-us/library/ms680339(VS.85).aspx
  //
  // Copy the fields we care about.
  size_of_code_ = ReadU32(optional_header_, 4);
  size_of_initialized_data_ = ReadU32(optional_header_, 8);
  size_of_uninitialized_data_ = ReadU32(optional_header_, 12);
  base_of_code_ = ReadU32(optional_header_, 20);

  switch (kind()) {
    case EXE_WIN_32_X86:
      base_of_data_ = ReadU32(optional_header_, 24);
      image_base_ = ReadU32(optional_header_, 28);
      size_of_image_ = ReadU32(optional_header_, 56);
      number_of_data_directories_ = ReadU32(optional_header_, 92);
      break;

    case EXE_WIN_32_X64:
      base_of_data_ = 0;
      image_base_ = ReadU64(optional_header_, 24);
      size_of_image_ = ReadU32(optional_header_, 56);
      number_of_data_directories_ = ReadU32(optional_header_, 108);
      break;

    default:
      NOTREACHED();
  }

  if (size_of_image_ >= 0x80000000U)
    return Bad("Invalid SizeOfImage");

  if (size_of_code_ >= length() || size_of_initialized_data_ >= length() ||
      size_of_code_ + size_of_initialized_data_ >= length()) {
    // This validation fires on some perfectly fine executables.
    //  return Bad("code or initialized data too big");
  }

  // TODO(sra): we can probably get rid of most of the data directories.
  bool b = true;
  // 'b &= ...' could be short circuit 'b = b && ...' but it is not necessary
  // for correctness and it compiles smaller this way.
  b &= ReadDataDirectory(0, &export_table_);
  b &= ReadDataDirectory(1, &import_table_);
  b &= ReadDataDirectory(2, &resource_table_);
  b &= ReadDataDirectory(3, &exception_table_);
  b &= ReadDataDirectory(5, &base_relocation_table_);
  b &= ReadDataDirectory(11, &bound_import_table_);
  b &= ReadDataDirectory(12, &import_address_table_);
  b &= ReadDataDirectory(13, &delay_import_descriptor_);
  b &= ReadDataDirectory(14, &clr_runtime_header_);
  if (!b)
    return Bad("Malformed data directory");

  // Sections follow the optional header.
  FileOffset sections_offset =
      optional_header_offset + size_of_optional_header_;
  if (!IsArrayInBounds(sections_offset, number_of_sections_, sizeof(Section)))
    return Bad("Sections past end of file");
  sections_ = reinterpret_cast<const Section*>(start() + sections_offset);
  if (!CheckSectionRanges())
    return Bad("Out of bound section");

  size_t detected_length = 0;
  for (int i = 0; i < number_of_sections_; ++i) {
    const Section* section = &sections_[i];

    // TODO(sra): consider using the 'characteristics' field of the section
    // header to see if the section contains instructions.
    if (memcmp(section->name, ".text", 6) == 0)
      has_text_section_ = true;

    uint32_t section_end =
        section->file_offset_of_raw_data + section->size_of_raw_data;
    if (section_end > detected_length)
      detected_length = section_end;
  }

  // Pretend our in-memory copy is only as long as our detected length.
  ReduceLength(detected_length);

  if (!has_text_section()) {
    return Bad("Resource-only executables are not yet supported");
  }

  return Good();
}

////////////////////////////////////////////////////////////////////////////////

bool DisassemblerWin32::ParseRelocs(std::vector<RVA>* relocs) {
  relocs->clear();

  size_t relocs_size = base_relocation_table_.size_;
  if (relocs_size == 0)
    return true;

  // The format of the base relocation table is a sequence of variable sized
  // IMAGE_BASE_RELOCATION blocks.  Search for
  //   "The format of the base relocation data is somewhat quirky"
  // at http://msdn.microsoft.com/en-us/library/ms809762.aspx

  const uint8_t* relocs_start = RVAToPointer(base_relocation_table_.address_);
  if (relocs_start == nullptr || relocs_start < start() ||
      relocs_start >= end())
    return Bad(".relocs outside image");

  // Make sure entire base relocation table is within the buffer.
  if (relocs_size > static_cast<size_t>(end() - relocs_start))
    return Bad(".relocs outside image");
  const uint8_t* relocs_end = relocs_start + relocs_size;

  const uint8_t* block = relocs_start;

  // Walk the variable sized blocks.
  while (block + 8 < relocs_end) {
    RVA page_rva = ReadU32(block, 0);
    uint32_t size = ReadU32(block, 4);
    if (size < 8 ||     // Size includes header ...
        size % 4 != 0)  // ... and is word aligned.
      return Bad("Unreasonable relocs block");

    const uint8_t* end_entries = block + size;

    if (end_entries <= block || end_entries <= start() || end_entries > end())
      return Bad(".relocs block outside image");

    // Walk through the two-byte entries.
    for (const uint8_t* p = block + 8; p < end_entries; p += 2) {
      uint16_t entry = ReadU16(p, 0);
      int type = entry >> 12;
      int offset = entry & 0xFFF;

      RVA rva = page_rva + offset;
      // Skip the relocs that live outside of the image. It might be the case
      // if a reloc is relative to a register, e.g.:
      //     mov    ecx,dword ptr [eax+044D5888h]
      RVA target_rva = PointerToTargetRVA(RVAToPointer(rva));
      if (target_rva == kNoRVA) {
        continue;
      }

      if (SupportsRelTableType(type)) {
        relocs->push_back(rva);
      } else if (type == 0) {  // IMAGE_REL_BASED_ABSOLUTE
        // Ignore, used as padding.
      } else {
        // Does not occur in Windows x86/x64 executables.
        return Bad("Unknown type of reloc");
      }
    }

    block += size;
  }

  std::sort(relocs->begin(), relocs->end());
  DCHECK(relocs->empty() || relocs->back() != kUnassignedRVA);

  return true;
}

const Section* DisassemblerWin32::RVAToSection(RVA rva) const {
  for (int i = 0; i < number_of_sections_; ++i) {
    const Section* section = &sections_[i];
    if (rva >= section->virtual_address) {
      FileOffset offset_in_section = rva - section->virtual_address;
      if (offset_in_section < section->virtual_size)
        return section;
    }
  }
  return nullptr;
}

std::string DisassemblerWin32::SectionName(const Section* section) {
  if (section == nullptr)
    return "<none>";
  char name[9];
  memcpy(name, section->name, 8);
  name[8] = '\0';  // Ensure termination.
  return name;
}

// static
bool DisassemblerWin32::QuickDetect(const uint8_t* start,
                                    size_t length,
                                    uint16_t magic) {
  if (length < kOffsetOfFileAddressOfNewExeHeader + 4)
    return false;

  // Have 'MZ' magic for a DOS header?
  if (start[0] != 'M' || start[1] != 'Z')
    return false;

  FileOffset pe_header_offset = static_cast<FileOffset>(
      ReadU32(start, kOffsetOfFileAddressOfNewExeHeader));
  if (pe_header_offset % 8 != 0 ||
      pe_header_offset < kOffsetOfFileAddressOfNewExeHeader + 4 ||
      pe_header_offset >= length ||
      length - pe_header_offset < kMinPeHeaderSize) {
    return false;
  }
  const uint8_t* pe_header = start + pe_header_offset;
  if (!(pe_header[0] == 'P' && pe_header[1] == 'E' && pe_header[2] == 0 &&
        pe_header[3] == 0)) {
    return false;
  }

  FileOffset optional_header_offset = pe_header_offset + kMinPeHeaderSize;
  if (optional_header_offset >= length || length - optional_header_offset < 2)
    return false;
  const uint8_t* optional_header = start + optional_header_offset;
  return magic == ReadU16(optional_header, 0);
}

bool DisassemblerWin32::IsRvaRangeInBounds(size_t start, size_t length) {
  return start < size_of_image_ && length <= size_of_image_ - start;
}

bool DisassemblerWin32::CheckSectionRanges() {
  for (int i = 0; i < number_of_sections_; ++i) {
    const Section* section = &sections_[i];
    if (!IsRangeInBounds(section->file_offset_of_raw_data,
                         section->size_of_raw_data) ||
        !IsRvaRangeInBounds(section->virtual_address, section->virtual_size)) {
      return false;
    }
  }
  return true;
}

bool DisassemblerWin32::ExtractAbs32Locations() {
  abs32_locations_.clear();
  if (!ParseRelocs(&abs32_locations_))
    return false;

#if COURGETTE_HISTOGRAM_TARGETS
  for (size_t i = 0; i < abs32_locations_.size(); ++i) {
    RVA rva = abs32_locations_[i];
    // The 4 bytes at the relocation are a reference to some address.
    ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))];
  }
#endif
  return true;
}

bool DisassemblerWin32::ExtractRel32Locations() {
  FileOffset file_offset = 0;
  while (file_offset < length()) {
    const Section* section = FindNextSection(file_offset);
    if (section == nullptr)
      break;
    if (file_offset < section->file_offset_of_raw_data)
      file_offset = section->file_offset_of_raw_data;
    ParseRel32RelocsFromSection(section);
    file_offset += section->size_of_raw_data;
  }
  std::sort(rel32_locations_.begin(), rel32_locations_.end());
  DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA);

#if COURGETTE_HISTOGRAM_TARGETS
  VLOG(1) << "abs32_locations_ " << abs32_locations_.size()
          << "\nrel32_locations_ " << rel32_locations_.size()
          << "\nabs32_target_rvas_ " << abs32_target_rvas_.size()
          << "\nrel32_target_rvas_ " << rel32_target_rvas_.size();

  int common = 0;
  std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin();
  std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin();
  while (abs32_iter != abs32_target_rvas_.end() &&
         rel32_iter != rel32_target_rvas_.end()) {
    if (abs32_iter->first < rel32_iter->first) {
      ++abs32_iter;
    } else if (rel32_iter->first < abs32_iter->first) {
      ++rel32_iter;
    } else {
      ++common;
      ++abs32_iter;
      ++rel32_iter;
    }
  }
  VLOG(1) << "common " << common;
#endif
  return true;
}

RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() {
  return new RvaVisitor_Abs32(abs32_locations_, *this);
}

RvaVisitor* DisassemblerWin32::CreateRel32TargetRvaVisitor() {
  return new RvaVisitor_Rel32(rel32_locations_, *this);
}

void DisassemblerWin32::RemoveUnusedRel32Locations(
    AssemblyProgram* program) {
  auto cond = [this, program](RVA rva) -> bool {
    // + 4 since offset is relative to start of next instruction.
    RVA target_rva = rva + 4 + Read32LittleEndian(RVAToPointer(rva));
    return program->FindRel32Label(target_rva) == nullptr;
  };
  rel32_locations_.erase(
      std::remove_if(rel32_locations_.begin(), rel32_locations_.end(), cond),
      rel32_locations_.end());
}

InstructionGenerator DisassemblerWin32::GetInstructionGenerator(
    AssemblyProgram* program) {
  return base::BindRepeating(&DisassemblerWin32::ParseFile,
                             base::Unretained(this), program);
}

CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program,
                                       InstructionReceptor* receptor) const {
  // Walk all the bytes in the file, whether or not in a section.
  FileOffset file_offset = 0;
  while (file_offset < length()) {
    const Section* section = FindNextSection(file_offset);
    if (section == nullptr) {
      // No more sections. There should not be extra stuff following last
      // section.
      //   ParseNonSectionFileRegion(file_offset, pe_info().length(), receptor);
      break;
    }
    if (file_offset < section->file_offset_of_raw_data) {
      FileOffset section_start_offset = section->file_offset_of_raw_data;
      if (!ParseNonSectionFileRegion(file_offset, section_start_offset,
                                     receptor)) {
        return false;
      }

      file_offset = section_start_offset;
    }
    FileOffset end = file_offset + section->size_of_raw_data;
    if (!ParseFileRegion(section, file_offset, end, program, receptor))
      return false;
    file_offset = end;
  }

#if COURGETTE_HISTOGRAM_TARGETS
  HistogramTargets("abs32 relocs", abs32_target_rvas_);
  HistogramTargets("rel32 relocs", rel32_target_rvas_);
#endif

  return true;
}

CheckBool DisassemblerWin32::ParseNonSectionFileRegion(
    FileOffset start_file_offset,
    FileOffset end_file_offset,
    InstructionReceptor* receptor) const {
  if (incomplete_disassembly_)
    return true;

  if (end_file_offset > start_file_offset) {
    if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset),
                                     end_file_offset - start_file_offset)) {
      return false;
    }
  }

  return true;
}

CheckBool DisassemblerWin32::ParseFileRegion(
    const Section* section,
    FileOffset start_file_offset,
    FileOffset end_file_offset,
    AssemblyProgram* program,
    InstructionReceptor* receptor) const {
  RVA relocs_start_rva = base_relocation_table().address_;

  const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset);
  const uint8_t* end_pointer = FileOffsetToPointer(end_file_offset);

  RVA start_rva = FileOffsetToRVA(start_file_offset);
  RVA end_rva = start_rva + section->virtual_size;
  const int kVAWidth = AbsVAWidth();

  // Quick way to convert from Pointer to RVA within a single Section is to
  // subtract 'pointer_to_rva'.
  const uint8_t* const adjust_pointer_to_rva = start_pointer - start_rva;

  std::vector<RVA>::const_iterator rel32_pos = rel32_locations_.begin();
  std::vector<RVA>::const_iterator abs32_pos = abs32_locations_.begin();

  if (!receptor->EmitOrigin(start_rva))
    return false;

  const uint8_t* p = start_pointer;

  while (p < end_pointer) {
    RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva);

    // The base relocation table is usually in the .relocs section, but it could
    // actually be anywhere.  Make sure we skip it because we will regenerate it
    // during assembly.
    if (current_rva == relocs_start_rva) {
      if (!receptor->EmitPeRelocs())
        return false;
      uint32_t relocs_size = base_relocation_table().size_;
      if (relocs_size) {
        p += relocs_size;
        continue;
      }
    }

    while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva)
      ++abs32_pos;

    if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) {
      RVA target_rva = PointerToTargetRVA(p);
      DCHECK_NE(kNoRVA, target_rva);
      // TODO(sra): target could be Label+offset.  It is not clear how to guess
      // which it might be.  We assume offset==0.
      Label* label = program->FindAbs32Label(target_rva);
      DCHECK(label);
      if (!EmitAbs(label, receptor))
        return false;
      p += kVAWidth;
      continue;
    }

    while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva)
      ++rel32_pos;

    if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) {
      // + 4 since offset is relative to start of next instruction.
      RVA target_rva = current_rva + 4 + Read32LittleEndian(p);
      Label* label = program->FindRel32Label(target_rva);
      DCHECK(label);
      if (!receptor->EmitRel32(label))
        return false;
      p += 4;
      continue;
    }

    if (incomplete_disassembly_) {
      if ((abs32_pos == abs32_locations_.end() || end_rva <= *abs32_pos) &&
          (rel32_pos == rel32_locations_.end() || end_rva <= *rel32_pos) &&
          (end_rva <= relocs_start_rva || current_rva >= relocs_start_rva)) {
        // No more relocs in this section, don't bother encoding bytes.
        break;
      }
    }

    if (!receptor->EmitSingleByte(*p))
      return false;
    p += 1;
  }

  return true;
}

#if COURGETTE_HISTOGRAM_TARGETS
// Histogram is printed to std::cout.  It is purely for debugging the algorithm
// and is only enabled manually in 'exploration' builds.  I don't want to add
// command-line configuration for this feature because this code has to be
// small, which means compiled-out.
void DisassemblerWin32::HistogramTargets(const char* kind,
                                         const std::map<RVA, int>& map) const {
  int total = 0;
  std::map<int, std::vector<RVA>> h;
  for (std::map<RVA, int>::const_iterator p = map.begin(); p != map.end();
       ++p) {
    h[p->second].push_back(p->first);
    total += p->second;
  }

  std::cout << total << " " << kind << " to " << map.size() << " unique targets"
            << std::endl;

  std::cout << "indegree: #targets-with-indegree (example)" << std::endl;
  const int kFirstN = 15;
  bool someSkipped = false;
  int index = 0;
  for (std::map<int, std::vector<RVA>>::reverse_iterator p = h.rbegin();
       p != h.rend(); ++p) {
    ++index;
    if (index <= kFirstN || p->first <= 3) {
      if (someSkipped) {
        std::cout << "..." << std::endl;
      }
      size_t count = p->second.size();
      std::cout << std::dec << p->first << ": " << count;
      if (count <= 2) {
        for (size_t i = 0; i < count; ++i)
          std::cout << "  " << DescribeRVA(p->second[i]);
      }
      std::cout << std::endl;
      someSkipped = false;
    } else {
      someSkipped = true;
    }
  }
}
#endif  // COURGETTE_HISTOGRAM_TARGETS

// DescribeRVA is for debugging only.  I would put it under #ifdef DEBUG except
// that during development I'm finding I need to call it when compiled in
// Release mode.  Hence:
// TODO(sra): make this compile only for debug mode.
std::string DisassemblerWin32::DescribeRVA(RVA rva) const {
  const Section* section = RVAToSection(rva);
  std::ostringstream s;
  s << std::hex << rva;
  if (section) {
    s << " (";
    s << SectionName(section) << "+" << std::hex
      << (rva - section->virtual_address) << ")";
  }
  return s.str();
}

const Section* DisassemblerWin32::FindNextSection(
    FileOffset file_offset) const {
  const Section* best = nullptr;
  for (int i = 0; i < number_of_sections_; ++i) {
    const Section* section = &sections_[i];
    if (section->size_of_raw_data > 0) {  // i.e. has data in file.
      if (file_offset <= section->file_offset_of_raw_data) {
        if (best == nullptr ||
            section->file_offset_of_raw_data < best->file_offset_of_raw_data) {
          best = section;
        }
      }
    }
  }
  return best;
}

bool DisassemblerWin32::ReadDataDirectory(int index,
                                          ImageDataDirectory* directory) {
  if (index < number_of_data_directories_) {
    FileOffset file_offset = index * 8 + RelativeOffsetOfDataDirectories();
    if (file_offset >= size_of_optional_header_)
      return Bad("Number of data directories inconsistent");
    const uint8_t* data_directory = optional_header_ + file_offset;
    if (data_directory < start() || data_directory + 8 >= end())
      return Bad("Data directory outside image");
    RVA rva = ReadU32(data_directory, 0);
    size_t size = ReadU32(data_directory, 4);
    if (size > size_of_image_)
      return Bad("Data directory size too big");

    // TODO(sra): validate RVA.
    directory->address_ = rva;
    directory->size_ = static_cast<uint32_t>(size);
    return true;
  } else {
    directory->address_ = 0;
    directory->size_ = 0;
    return true;
  }
}

}  // namespace courgette
