// Copyright 2021 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "client/ios_handler/in_process_intermediate_dump_handler.h"

#include <mach-o/dyld_images.h>
#include <mach-o/nlist.h>
#include <stdint.h>
#include <string.h>
#include <sys/sysctl.h>
#include <time.h>

#include "base/cxx17_backports.h"
#include "build/build_config.h"
#include "snapshot/snapshot_constants.h"
#include "util/ios/ios_intermediate_dump_writer.h"
#include "util/ios/raw_logging.h"
#include "util/ios/scoped_vm_read.h"

namespace crashpad {
namespace internal {

namespace {

#if defined(ARCH_CPU_X86_64)
const thread_state_flavor_t kThreadStateFlavor = x86_THREAD_STATE64;
const thread_state_flavor_t kFloatStateFlavor = x86_FLOAT_STATE64;
const thread_state_flavor_t kDebugStateFlavor = x86_DEBUG_STATE64;
using thread_state_type = x86_thread_state64_t;
#elif defined(ARCH_CPU_ARM64)
const thread_state_flavor_t kThreadStateFlavor = ARM_THREAD_STATE64;
const thread_state_flavor_t kFloatStateFlavor = ARM_NEON_STATE64;
const thread_state_flavor_t kDebugStateFlavor = ARM_DEBUG_STATE64;
using thread_state_type = arm_thread_state64_t;
#endif

// From snapshot/mac/process_types/crashreporterclient.proctype
struct crashreporter_annotations_t {
  uint64_t version;
  uint64_t message;
  uint64_t signature_string;
  uint64_t backtrace;
  uint64_t message2;
  uint64_t thread;
  uint64_t dialog_mode;
  uint64_t abort_cause;
};

//! \brief Manage memory and ports after calling `task_threads`.
class ScopedTaskThreads {
 public:
  explicit ScopedTaskThreads(thread_act_array_t threads,
                             mach_msg_type_number_t thread_count)
      : threads_(threads), thread_count_(thread_count) {}

  ScopedTaskThreads(const ScopedTaskThreads&) = delete;
  ScopedTaskThreads& operator=(const ScopedTaskThreads&) = delete;

  ~ScopedTaskThreads() {
    for (uint32_t thread_index = 0; thread_index < thread_count_;
         ++thread_index) {
      mach_port_deallocate(mach_task_self(), threads_[thread_index]);
    }
    vm_deallocate(mach_task_self(),
                  reinterpret_cast<vm_address_t>(threads_),
                  sizeof(thread_t) * thread_count_);
  }

 private:
  thread_act_array_t threads_;
  mach_msg_type_number_t thread_count_;
};

//! \brief Log \a key as a string.
void WriteError(IntermediateDumpKey key) {
  CRASHPAD_RAW_LOG("Unable to write key");
  switch (key) {
// clang-format off
#define CASE_KEY(Name, Value)       \
    case IntermediateDumpKey::Name: \
      CRASHPAD_RAW_LOG(#Name);      \
      break;
    INTERMEDIATE_DUMP_KEYS(CASE_KEY)
#undef CASE_KEY
    // clang-format on
  }
}

//! \brief Call AddProperty with raw error log.
//!
//! \param[in] writer The dump writer
//! \param[in] key The key to write.
//! \param[in] value Memory to be written.
//! \param[in] count Length of \a value.
template <typename T>
void WriteProperty(IOSIntermediateDumpWriter* writer,
                   IntermediateDumpKey key,
                   const T* value,
                   size_t count = 1) {
  if (!writer->AddProperty(key, value, count))
    WriteError(key);
}

//! \brief Call AddPropertyBytes with raw error log.
//!
//! \param[in] writer The dump writer
//! \param[in] key The key to write.
//! \param[in] value Memory to be written.
//! \param[in] count Length of \a data.
void WritePropertyBytes(IOSIntermediateDumpWriter* writer,
                        IntermediateDumpKey key,
                        const void* value,
                        size_t value_length) {
  if (!writer->AddPropertyBytes(key, value, value_length))
    WriteError(key);
}

kern_return_t MachVMRegionRecurseDeepest(task_t task,
                                         vm_address_t* address,
                                         vm_size_t* size,
                                         natural_t* depth,
                                         vm_prot_t* protection,
                                         unsigned int* user_tag) {
  vm_region_submap_short_info_64 submap_info;
  mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
  while (true) {
    // Note: vm_region_recurse() would be fine here, but it does not provide
    // VM_REGION_SUBMAP_SHORT_INFO_COUNT.
    kern_return_t kr = vm_region_recurse_64(
        task,
        address,
        size,
        depth,
        reinterpret_cast<vm_region_recurse_info_t>(&submap_info),
        &count);
    if (kr != KERN_SUCCESS) {
      CRASHPAD_RAW_LOG_ERROR(kr, "vm_region_recurse_64");
      return kr;
    }

    if (!submap_info.is_submap) {
      *protection = submap_info.protection;
      *user_tag = submap_info.user_tag;
      return KERN_SUCCESS;
    }

    ++*depth;
  }
}

//! \brief Adjusts the region for the red zone, if the ABI requires one.
//!
//! This method performs red zone calculation for CalculateStackRegion(). Its
//! parameters are local variables used within that method, and may be
//! modified as needed.
//!
//! Where a red zone is required, the region of memory captured for a thread’s
//! stack will be extended to include the red zone below the stack pointer,
//! provided that such memory is mapped, readable, and has the correct user
//! tag value. If these conditions cannot be met fully, as much of the red
//! zone will be captured as is possible while meeting these conditions.
//!
//! \param[in,out] start_address The base address of the region to begin
//!     capturing stack memory from. On entry, \a start_address is the stack
//!     pointer. On return, \a start_address may be decreased to encompass a
//!     red zone.
//! \param[in,out] region_base The base address of the region that contains
//!     stack memory. This is distinct from \a start_address in that \a
//!     region_base will be page-aligned. On entry, \a region_base is the
//!     base address of a region that contains \a start_address. On return,
//!     if \a start_address is decremented and is outside of the region
//!     originally described by \a region_base, \a region_base will also be
//!     decremented appropriately.
//! \param[in,out] region_size The size of the region that contains stack
//!     memory. This region begins at \a region_base. On return, if \a
//!     region_base is decremented, \a region_size will be incremented
//!     appropriately.
//! \param[in] user_tag The Mach VM system’s user tag for the region described
//!     by the initial values of \a region_base and \a region_size. The red
//!     zone will only be allowed to extend out of the region described by
//!     these initial values if the user tag is appropriate for stack memory
//!     and the expanded region has the same user tag value.
void LocateRedZone(vm_address_t* const start_address,
                   vm_address_t* const region_base,
                   vm_address_t* const region_size,
                   const unsigned int user_tag) {
  // x86_64 has a red zone. See AMD64 ABI 0.99.8,
  // https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/uploads/01de35b2c8adc7545de52604cc45d942/x86-64-psABI-2021-05-20.pdf#page=23.
  // section 3.2.2, “The Stack Frame”.
  // So does ARM64,
  // https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Respect-the-Stacks-Red-Zone
  // section "Respect the Stack’s Red Zone".
  constexpr vm_size_t kRedZoneSize = 128;
  vm_address_t red_zone_base =
      *start_address >= kRedZoneSize ? *start_address - kRedZoneSize : 0;
  bool red_zone_ok = false;
  if (red_zone_base >= *region_base) {
    // The red zone is within the region already discovered.
    red_zone_ok = true;
  } else if (red_zone_base < *region_base && user_tag == VM_MEMORY_STACK) {
    // Probe to see if there’s a region immediately below the one already
    // discovered.
    vm_address_t red_zone_region_base = red_zone_base;
    vm_size_t red_zone_region_size;
    natural_t red_zone_depth = 0;
    vm_prot_t red_zone_protection;
    unsigned int red_zone_user_tag;
    kern_return_t kr = MachVMRegionRecurseDeepest(mach_task_self(),
                                                  &red_zone_region_base,
                                                  &red_zone_region_size,
                                                  &red_zone_depth,
                                                  &red_zone_protection,
                                                  &red_zone_user_tag);
    if (kr != KERN_SUCCESS) {
      *start_address = *region_base;
    } else if (red_zone_region_base + red_zone_region_size == *region_base &&
               (red_zone_protection & VM_PROT_READ) != 0 &&
               red_zone_user_tag == user_tag) {
      // The region containing the red zone is immediately below the region
      // already found, it’s readable (not the guard region), and it has the
      // same user tag as the region already found, so merge them.
      red_zone_ok = true;
      *region_base -= red_zone_region_size;
      *region_size += red_zone_region_size;
    }
  }

  if (red_zone_ok) {
    // Begin capturing from the base of the red zone (but not the entire
    // region that encompasses the red zone).
    *start_address = red_zone_base;
  } else {
    // The red zone would go lower into another region in memory, but no
    // region was found. Memory can only be captured to an address as low as
    // the base address of the region already found.
    *start_address = *region_base;
  }
}

//! \brief Calculates the base address and size of the region used as a
//!     thread’s stack.
//!
//! The region returned by this method may be formed by merging multiple
//! adjacent regions in a process’ memory map if appropriate. The base address
//! of the returned region may be lower than the \a stack_pointer passed in
//! when the ABI mandates a red zone below the stack pointer.
//!
//! \param[in] stack_pointer The stack pointer, referring to the top (lowest
//!     address) of a thread’s stack.
//! \param[out] stack_region_size The size of the memory region used as the
//!     thread’s stack.
//!
//! \return The base address (lowest address) of the memory region used as the
//!     thread’s stack.
vm_address_t CalculateStackRegion(vm_address_t stack_pointer,
                                  vm_size_t* stack_region_size) {
  // For pthreads, it may be possible to compute the stack region based on the
  // internal _pthread::stackaddr and _pthread::stacksize. The _pthread struct
  // for a thread can be located at TSD slot 0, or the known offsets of
  // stackaddr and stacksize from the TSD area could be used.
  vm_address_t region_base = stack_pointer;
  vm_size_t region_size;
  natural_t depth = 0;
  vm_prot_t protection;
  unsigned int user_tag;
  kern_return_t kr = MachVMRegionRecurseDeepest(mach_task_self(),
                                                &region_base,
                                                &region_size,
                                                &depth,
                                                &protection,
                                                &user_tag);
  if (kr != KERN_SUCCESS) {
    CRASHPAD_RAW_LOG_ERROR(kr, "MachVMRegionRecurseDeepest");
    *stack_region_size = 0;
    return 0;
  }

  if (region_base > stack_pointer) {
    // There’s nothing mapped at the stack pointer’s address. Something may have
    // trashed the stack pointer. Note that this shouldn’t happen for a normal
    // stack guard region violation because the guard region is mapped but has
    // VM_PROT_NONE protection.
    *stack_region_size = 0;
    return 0;
  }

  vm_address_t start_address = stack_pointer;

  if ((protection & VM_PROT_READ) == 0) {
    // If the region isn’t readable, the stack pointer probably points to the
    // guard region. Don’t include it as part of the stack, and don’t include
    // anything at any lower memory address. The code below may still possibly
    // find the real stack region at a memory address higher than this region.
    start_address = region_base + region_size;
  } else {
    // If the ABI requires a red zone, adjust the region to include it if
    // possible.
    LocateRedZone(&start_address, &region_base, &region_size, user_tag);

    // Regardless of whether the ABI requires a red zone, capture up to
    // kExtraCaptureSize additional bytes of stack, but only if present in the
    // region that was already found.
    constexpr vm_size_t kExtraCaptureSize = 128;
    start_address = std::max(start_address >= kExtraCaptureSize
                                 ? start_address - kExtraCaptureSize
                                 : start_address,
                             region_base);

    // Align start_address to a 16-byte boundary, which can help readers by
    // ensuring that data is aligned properly. This could page-align instead,
    // but that might be wasteful.
    constexpr vm_size_t kDesiredAlignment = 16;
    start_address &= ~(kDesiredAlignment - 1);
    DCHECK_GE(start_address, region_base);
  }

  region_size -= (start_address - region_base);
  region_base = start_address;

  vm_size_t total_region_size = region_size;

  // The stack region may have gotten split up into multiple abutting regions.
  // Try to coalesce them. This frequently happens for the main thread’s stack
  // when setrlimit(RLIMIT_STACK, …) is called. It may also happen if a region
  // is split up due to an mprotect() or vm_protect() call.
  //
  // Stack regions created by the kernel and the pthreads library will be marked
  // with the VM_MEMORY_STACK user tag. Scanning for multiple adjacent regions
  // with the same tag should find an entire stack region. Checking that the
  // protection on individual regions is not VM_PROT_NONE should guarantee that
  // this algorithm doesn’t collect map entries belonging to another thread’s
  // stack: well-behaved stacks (such as those created by the kernel and the
  // pthreads library) have VM_PROT_NONE guard regions at their low-address
  // ends.
  //
  // Other stack regions may not be so well-behaved and thus if user_tag is not
  // VM_MEMORY_STACK, the single region that was found is used as-is without
  // trying to merge it with other adjacent regions.
  if (user_tag == VM_MEMORY_STACK) {
    vm_address_t try_address = region_base;
    vm_address_t original_try_address;

    while (try_address += region_size,
           original_try_address = try_address,
           (kr = MachVMRegionRecurseDeepest(mach_task_self(),
                                            &try_address,
                                            &region_size,
                                            &depth,
                                            &protection,
                                            &user_tag) == KERN_SUCCESS) &&
               try_address == original_try_address &&
               (protection & VM_PROT_READ) != 0 &&
               user_tag == VM_MEMORY_STACK) {
      total_region_size += region_size;
    }

    if (kr != KERN_SUCCESS && kr != KERN_INVALID_ADDRESS) {
      // Tolerate KERN_INVALID_ADDRESS because it will be returned when there
      // are no more regions in the map at or above the specified |try_address|.
      CRASHPAD_RAW_LOG_ERROR(kr, "MachVMRegionRecurseDeepest");
    }
  }

  *stack_region_size = total_region_size;
  return region_base;
}

//! \brief Write data around \a address to intermediate dump. Must be called
//!    from within a ScopedArray.
void MaybeCaptureMemoryAround(IOSIntermediateDumpWriter* writer,
                              uint64_t address) {
  constexpr uint64_t non_address_offset = 0x10000;
  if (address < non_address_offset)
    return;

  constexpr uint64_t max_address = std::numeric_limits<uint64_t>::max();

  if (address > max_address - non_address_offset)
    return;

  constexpr uint64_t kRegisterByteOffset = 128;
  const uint64_t target = address - kRegisterByteOffset;
  constexpr uint64_t size = 512;
  static_assert(kRegisterByteOffset <= size / 2, "negative offset too large");

  IOSIntermediateDumpWriter::ScopedArrayMap memory_region(writer);
  WriteProperty(
      writer, IntermediateDumpKey::kThreadContextMemoryRegionAddress, &address);
  // Don't use WritePropertyBytes, this one will fail regularly if |target|
  // cannot be read.
  writer->AddPropertyBytes(IntermediateDumpKey::kThreadContextMemoryRegionData,
                           reinterpret_cast<const void*>(target),
                           size);
}

void CaptureMemoryPointedToByThreadState(IOSIntermediateDumpWriter* writer,
                                         thread_state_type thread_state) {
  IOSIntermediateDumpWriter::ScopedArray memory_regions(
      writer, IntermediateDumpKey::kThreadContextMemoryRegions);

#if defined(ARCH_CPU_X86_64)
  MaybeCaptureMemoryAround(writer, thread_state.__rax);
  MaybeCaptureMemoryAround(writer, thread_state.__rbx);
  MaybeCaptureMemoryAround(writer, thread_state.__rcx);
  MaybeCaptureMemoryAround(writer, thread_state.__rdx);
  MaybeCaptureMemoryAround(writer, thread_state.__rdi);
  MaybeCaptureMemoryAround(writer, thread_state.__rsi);
  MaybeCaptureMemoryAround(writer, thread_state.__rbp);
  MaybeCaptureMemoryAround(writer, thread_state.__r8);
  MaybeCaptureMemoryAround(writer, thread_state.__r9);
  MaybeCaptureMemoryAround(writer, thread_state.__r10);
  MaybeCaptureMemoryAround(writer, thread_state.__r11);
  MaybeCaptureMemoryAround(writer, thread_state.__r12);
  MaybeCaptureMemoryAround(writer, thread_state.__r13);
  MaybeCaptureMemoryAround(writer, thread_state.__r14);
  MaybeCaptureMemoryAround(writer, thread_state.__r15);
  MaybeCaptureMemoryAround(writer, thread_state.__rip);
#elif defined(ARCH_CPU_ARM_FAMILY)
  MaybeCaptureMemoryAround(writer, thread_state.__pc);
  for (size_t i = 0; i < base::size(thread_state.__x); ++i) {
    MaybeCaptureMemoryAround(writer, thread_state.__x[i]);
  }
#endif
}

void WriteCrashpadSimpleAnnotationsDictionary(IOSIntermediateDumpWriter* writer,
                                              CrashpadInfo* crashpad_info) {
  if (!crashpad_info->simple_annotations())
    return;

  ScopedVMRead<SimpleStringDictionary> simple_annotations;
  if (!simple_annotations.Read(crashpad_info->simple_annotations())) {
    CRASHPAD_RAW_LOG("Unable to read simple annotations.");
    return;
  }

  const size_t count = simple_annotations->GetCount();
  if (!count)
    return;

  IOSIntermediateDumpWriter::ScopedArray annotations_array(
      writer, IntermediateDumpKey::kAnnotationsSimpleMap);

  SimpleStringDictionary::Entry* entries =
      reinterpret_cast<SimpleStringDictionary::Entry*>(
          simple_annotations.get());
  for (size_t index = 0; index < count; index++) {
    IOSIntermediateDumpWriter::ScopedArrayMap annotation_map(writer);
    const auto& entry = entries[index];
    size_t key_length = strnlen(entry.key, sizeof(entry.key));
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationName,
                       reinterpret_cast<const void*>(entry.key),
                       key_length);
    size_t value_length = strnlen(entry.value, sizeof(entry.value));
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationValue,
                       reinterpret_cast<const void*>(entry.value),
                       value_length);
  }
}

void WriteAppleCrashReporterAnnotations(
    IOSIntermediateDumpWriter* writer,
    crashreporter_annotations_t* crash_info) {
  // This number was totally made up out of nowhere, but it seems prudent to
  // enforce some limit.
  constexpr size_t kMaxMessageSize = 1024;
  IOSIntermediateDumpWriter::ScopedMap annotation_map(
      writer, IntermediateDumpKey::kAnnotationsCrashInfo);
  if (crash_info->message) {
    const size_t message_len = strnlen(
        reinterpret_cast<const char*>(crash_info->message), kMaxMessageSize);
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationsCrashInfoMessage1,
                       reinterpret_cast<const void*>(crash_info->message),
                       message_len);
  }
  if (crash_info->message2) {
    const size_t message_len = strnlen(
        reinterpret_cast<const char*>(crash_info->message2), kMaxMessageSize);
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationsCrashInfoMessage2,
                       reinterpret_cast<const void*>(crash_info->message2),
                       message_len);
  }
}

void WriteDyldErrorStringAnnotation(
    IOSIntermediateDumpWriter* writer,
    const uint64_t address,
    const symtab_command* symtab_command_ptr,
    const dysymtab_command* dysymtab_command_ptr,
    const segment_command_64* text_seg_ptr,
    const segment_command_64* linkedit_seg_ptr,
    vm_size_t slide) {
  if (text_seg_ptr == nullptr || linkedit_seg_ptr == nullptr ||
      symtab_command_ptr == nullptr) {
    return;
  }

  ScopedVMRead<symtab_command> symtab_command;
  ScopedVMRead<dysymtab_command> dysymtab_command;
  ScopedVMRead<segment_command_64> text_seg;
  ScopedVMRead<segment_command_64> linkedit_seg;
  if (!symtab_command.Read(symtab_command_ptr) ||
      !text_seg.Read(text_seg_ptr) || !linkedit_seg.Read(linkedit_seg_ptr) ||
      (dysymtab_command_ptr && !dysymtab_command.Read(dysymtab_command_ptr))) {
    CRASHPAD_RAW_LOG("Unable to load dyld symbol table.");
  }

  uint64_t file_slide =
      (linkedit_seg->vmaddr - text_seg->vmaddr) - linkedit_seg->fileoff;
  uint64_t strings = address + (symtab_command->stroff + file_slide);
  nlist_64* symbol_ptr = reinterpret_cast<nlist_64*>(
      address + (symtab_command->symoff + file_slide));

  // If a dysymtab is present, use it to filter the symtab for just the
  // portion used for extdefsym. If no dysymtab is present, the entire symtab
  // will need to be consulted.
  uint32_t symbol_count = symtab_command->nsyms;
  if (dysymtab_command_ptr) {
    symbol_ptr += dysymtab_command->iextdefsym;
    symbol_count = dysymtab_command->nextdefsym;
  }

  for (uint32_t i = 0; i < symbol_count; i++, symbol_ptr++) {
    ScopedVMRead<nlist_64> symbol;
    if (!symbol.Read(symbol_ptr)) {
      CRASHPAD_RAW_LOG("Unable to load dyld symbol table symbol.");
      return;
    }

    if (!symbol->n_value)
      continue;

    ScopedVMRead<const char> symbol_name;
    if (!symbol_name.Read(strings + symbol->n_un.n_strx)) {
      CRASHPAD_RAW_LOG("Unable to load dyld symbol name.");
    }

    if (strcmp(symbol_name.get(), "_error_string") == 0) {
      ScopedVMRead<const char> symbol_value;
      if (!symbol_value.Read(symbol->n_value + slide)) {
        CRASHPAD_RAW_LOG("Unable to load dyld symbol value.");
      }
      // 1024 here is distinct from kMaxMessageSize above, because it refers to
      // a precisely-sized buffer inside dyld.
      const size_t value_len = strnlen(symbol_value.get(), 1024);
      if (value_len) {
        WriteProperty(writer,
                      IntermediateDumpKey::kAnnotationsDyldErrorString,
                      symbol_value.get(),
                      value_len);
      }
      return;
    }

    continue;
  }
}

}  // namespace

// static
void InProcessIntermediateDumpHandler::WriteHeader(
    IOSIntermediateDumpWriter* writer) {
  static constexpr uint8_t version = 1;
  WriteProperty(writer, IntermediateDumpKey::kVersion, &version);
}

// static
void InProcessIntermediateDumpHandler::WriteProcessInfo(
    IOSIntermediateDumpWriter* writer) {
  IOSIntermediateDumpWriter::ScopedMap process_map(
      writer, IntermediateDumpKey::kProcessInfo);

  timeval snapshot_time;
  if (gettimeofday(&snapshot_time, nullptr) == 0) {
    WriteProperty(writer, IntermediateDumpKey::kSnapshotTime, &snapshot_time);
  } else {
    CRASHPAD_RAW_LOG("gettimeofday");
  }

  // Used by pid, parent pid and snapshot time.
  kinfo_proc kern_proc_info;
  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
  size_t len = sizeof(kern_proc_info);
  if (sysctl(mib, base::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) {
    WriteProperty(
        writer, IntermediateDumpKey::kPID, &kern_proc_info.kp_proc.p_pid);
    WriteProperty(writer,
                  IntermediateDumpKey::kParentPID,
                  &kern_proc_info.kp_eproc.e_ppid);
    WriteProperty(writer,
                  IntermediateDumpKey::kStartTime,
                  &kern_proc_info.kp_proc.p_starttime);
  } else {
    CRASHPAD_RAW_LOG("sysctl kern_proc_info");
  }

  // Used by user time and system time.
  mach_task_basic_info task_basic_info;
  mach_msg_type_number_t task_basic_info_count = MACH_TASK_BASIC_INFO_COUNT;
  kern_return_t kr = task_info(mach_task_self(),
                               MACH_TASK_BASIC_INFO,
                               reinterpret_cast<task_info_t>(&task_basic_info),
                               &task_basic_info_count);
  if (kr == KERN_SUCCESS) {
    IOSIntermediateDumpWriter::ScopedMap task_info(
        writer, IntermediateDumpKey::kTaskBasicInfo);

    WriteProperty(
        writer, IntermediateDumpKey::kUserTime, &task_basic_info.user_time);
    WriteProperty(
        writer, IntermediateDumpKey::kSystemTime, &task_basic_info.system_time);
  } else {
    CRASHPAD_RAW_LOG("task_info task_basic_info");
  }

  task_thread_times_info_data_t task_thread_times;
  mach_msg_type_number_t task_thread_times_count = TASK_THREAD_TIMES_INFO_COUNT;
  kr = task_info(mach_task_self(),
                 TASK_THREAD_TIMES_INFO,
                 reinterpret_cast<task_info_t>(&task_thread_times),
                 &task_thread_times_count);
  if (kr == KERN_SUCCESS) {
    IOSIntermediateDumpWriter::ScopedMap task_thread_times_map(
        writer, IntermediateDumpKey::kTaskThreadTimes);

    WriteProperty(
        writer, IntermediateDumpKey::kUserTime, &task_thread_times.user_time);
    WriteProperty(writer,
                  IntermediateDumpKey::kSystemTime,
                  &task_thread_times.system_time);
  } else {
    CRASHPAD_RAW_LOG("task_info task_basic_info");
  }
}

// static
void InProcessIntermediateDumpHandler::WriteSystemInfo(
    IOSIntermediateDumpWriter* writer,
    const IOSSystemDataCollector& system_data) {
  IOSIntermediateDumpWriter::ScopedMap system_map(
      writer, IntermediateDumpKey::kSystemInfo);

  const std::string& machine_description = system_data.MachineDescription();
  WriteProperty(writer,
                IntermediateDumpKey::kMachineDescription,
                machine_description.c_str(),
                machine_description.length());
  int os_version_major;
  int os_version_minor;
  int os_version_bugfix;
  system_data.OSVersion(
      &os_version_major, &os_version_minor, &os_version_bugfix);
  WriteProperty(
      writer, IntermediateDumpKey::kOSVersionMajor, &os_version_major);
  WriteProperty(
      writer, IntermediateDumpKey::kOSVersionMinor, &os_version_minor);
  WriteProperty(
      writer, IntermediateDumpKey::kOSVersionBugfix, &os_version_bugfix);
  const std::string& os_version_build = system_data.Build();
  WriteProperty(writer,
                IntermediateDumpKey::kOSVersionBuild,
                os_version_build.c_str(),
                os_version_build.length());

  int cpu_count = system_data.ProcessorCount();
  WriteProperty(writer, IntermediateDumpKey::kCpuCount, &cpu_count);
  const std::string& cpu_vendor = system_data.CPUVendor();
  WriteProperty(writer,
                IntermediateDumpKey::kCpuVendor,
                cpu_vendor.c_str(),
                cpu_vendor.length());

  bool has_daylight_saving_time = system_data.HasDaylightSavingTime();
  WriteProperty(writer,
                IntermediateDumpKey::kHasDaylightSavingTime,
                &has_daylight_saving_time);
  bool is_daylight_saving_time = system_data.IsDaylightSavingTime();
  WriteProperty(writer,
                IntermediateDumpKey::kIsDaylightSavingTime,
                &is_daylight_saving_time);
  int standard_offset_seconds = system_data.StandardOffsetSeconds();
  WriteProperty(writer,
                IntermediateDumpKey::kStandardOffsetSeconds,
                &standard_offset_seconds);
  int daylight_offset_seconds = system_data.DaylightOffsetSeconds();
  WriteProperty(writer,
                IntermediateDumpKey::kDaylightOffsetSeconds,
                &daylight_offset_seconds);
  const std::string& standard_name = system_data.StandardName();
  WriteProperty(writer,
                IntermediateDumpKey::kStandardName,
                standard_name.c_str(),
                standard_name.length());
  const std::string& daylight_name = system_data.DaylightName();
  WriteProperty(writer,
                IntermediateDumpKey::kDaylightName,
                daylight_name.c_str(),
                daylight_name.length());

  vm_size_t page_size;
  host_page_size(mach_host_self(), &page_size);
  WriteProperty(writer, IntermediateDumpKey::kPageSize, &page_size);

  mach_msg_type_number_t host_size =
      sizeof(vm_statistics_data_t) / sizeof(integer_t);
  vm_statistics_data_t vm_stat;
  kern_return_t kr = host_statistics(mach_host_self(),
                                     HOST_VM_INFO,
                                     reinterpret_cast<host_info_t>(&vm_stat),
                                     &host_size);
  if (kr == KERN_SUCCESS) {
    IOSIntermediateDumpWriter::ScopedMap vm_stat_map(
        writer, IntermediateDumpKey::kVMStat);

    WriteProperty(writer, IntermediateDumpKey::kActive, &vm_stat.active_count);
    WriteProperty(
        writer, IntermediateDumpKey::kInactive, &vm_stat.inactive_count);
    WriteProperty(writer, IntermediateDumpKey::kWired, &vm_stat.wire_count);
    WriteProperty(writer, IntermediateDumpKey::kFree, &vm_stat.free_count);
  } else {
    CRASHPAD_RAW_LOG("host_statistics");
  }
}

// static
void InProcessIntermediateDumpHandler::WriteThreadInfo(
    IOSIntermediateDumpWriter* writer,
    const uint64_t* frames,
    const size_t num_frames) {
  IOSIntermediateDumpWriter::ScopedArray thread_array(
      writer, IntermediateDumpKey::kThreads);

  // Exception thread ID.
  uint64_t exception_thread_id = 0;
  thread_identifier_info identifier_info;
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kern_return_t kr =
      thread_info(mach_thread_self(),
                  THREAD_IDENTIFIER_INFO,
                  reinterpret_cast<thread_info_t>(&identifier_info),
                  &count);
  if (kr == KERN_SUCCESS) {
    exception_thread_id = identifier_info.thread_id;
  } else {
    CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::THREAD_IDENTIFIER_INFO");
  }

  mach_msg_type_number_t thread_count = 0;
  thread_act_array_t threads;
  kr = task_threads(mach_task_self(), &threads, &thread_count);
  if (kr != KERN_SUCCESS) {
    CRASHPAD_RAW_LOG_ERROR(kr, "task_threads");
  }
  ScopedTaskThreads threads_vm_owner(threads, thread_count);

  for (uint32_t thread_index = 0; thread_index < thread_count; ++thread_index) {
    IOSIntermediateDumpWriter::ScopedArrayMap thread_map(writer);
    thread_t thread = threads[thread_index];

    thread_basic_info basic_info;
    mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
    kr = thread_info(thread,
                     THREAD_BASIC_INFO,
                     reinterpret_cast<thread_info_t>(&basic_info),
                     &count);
    if (kr == KERN_SUCCESS) {
      WriteProperty(writer,
                    IntermediateDumpKey::kSuspendCount,
                    &basic_info.suspend_count);
    } else {
      CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::THREAD_BASIC_INFO");
    }

    thread_precedence_policy precedence;
    count = THREAD_PRECEDENCE_POLICY_COUNT;
    boolean_t get_default = FALSE;
    kr = thread_policy_get(thread,
                           THREAD_PRECEDENCE_POLICY,
                           reinterpret_cast<thread_policy_t>(&precedence),
                           &count,
                           &get_default);
    if (kr == KERN_SUCCESS) {
      WriteProperty(
          writer, IntermediateDumpKey::kPriority, &precedence.importance);
    } else {
      CRASHPAD_RAW_LOG_ERROR(kr, "thread_policy_get");
    }

    // Thread ID.
    uint64_t thread_id;
    thread_identifier_info identifier_info;
    count = THREAD_IDENTIFIER_INFO_COUNT;
    kr = thread_info(thread,
                     THREAD_IDENTIFIER_INFO,
                     reinterpret_cast<thread_info_t>(&identifier_info),
                     &count);
    if (kr == KERN_SUCCESS) {
      thread_id = identifier_info.thread_id;
      WriteProperty(
          writer, IntermediateDumpKey::kThreadID, &identifier_info.thread_id);
      WriteProperty(writer,
                    IntermediateDumpKey::kThreadDataAddress,
                    &identifier_info.thread_handle);
    } else {
      CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::THREAD_IDENTIFIER_INFO");
    }

    // thread_snapshot_ios_intermediate_dump::GenerateStackMemoryFromFrames is
    // only implemented for arm64, so no x86_64 block here.
#if defined(ARCH_CPU_ARM64)
    // For uncaught NSExceptions, use the frames passed from the system rather
    // than the current thread state.
    if (num_frames > 0 && exception_thread_id == thread_id) {
      WriteProperty(writer,
                    IntermediateDumpKey::kThreadUncaughtNSExceptionFrames,
                    frames,
                    num_frames);
      continue;
    }
#endif

#if defined(ARCH_CPU_X86_64)
    x86_thread_state64_t thread_state;
    x86_float_state64_t float_state;
    x86_debug_state64_t debug_state;
    mach_msg_type_number_t thread_state_count = x86_THREAD_STATE64_COUNT;
    mach_msg_type_number_t float_state_count = x86_FLOAT_STATE64_COUNT;
    mach_msg_type_number_t debug_state_count = x86_DEBUG_STATE64_COUNT;
#elif defined(ARCH_CPU_ARM64)
    arm_thread_state64_t thread_state;
    arm_neon_state64_t float_state;
    arm_debug_state64_t debug_state;
    mach_msg_type_number_t thread_state_count = ARM_THREAD_STATE64_COUNT;
    mach_msg_type_number_t float_state_count = ARM_NEON_STATE64_COUNT;
    mach_msg_type_number_t debug_state_count = ARM_DEBUG_STATE64_COUNT;
#endif

    kern_return_t kr =
        thread_get_state(thread,
                         kThreadStateFlavor,
                         reinterpret_cast<thread_state_t>(&thread_state),
                         &thread_state_count);
    if (kr != KERN_SUCCESS) {
      CRASHPAD_RAW_LOG_ERROR(kr, "thread_get_state::kThreadStateFlavor");
    }
    WriteProperty(writer, IntermediateDumpKey::kThreadState, &thread_state);

    kr = thread_get_state(thread,
                          kFloatStateFlavor,
                          reinterpret_cast<thread_state_t>(&float_state),
                          &float_state_count);
    if (kr != KERN_SUCCESS) {
      CRASHPAD_RAW_LOG_ERROR(kr, "thread_get_state::kFloatStateFlavor");
    }
    WriteProperty(writer, IntermediateDumpKey::kFloatState, &float_state);

    kr = thread_get_state(thread,
                          kDebugStateFlavor,
                          reinterpret_cast<thread_state_t>(&debug_state),
                          &debug_state_count);
    if (kr != KERN_SUCCESS) {
      CRASHPAD_RAW_LOG_ERROR(kr, "thread_get_state::kDebugStateFlavor");
    }
    WriteProperty(writer, IntermediateDumpKey::kDebugState, &debug_state);

#if defined(ARCH_CPU_X86_64)
    vm_address_t stack_pointer = thread_state.__rsp;
#elif defined(ARCH_CPU_ARM64)
    vm_address_t stack_pointer = thread_state.__sp;
#endif

    vm_size_t stack_region_size;
    const vm_address_t stack_region_address =
        CalculateStackRegion(stack_pointer, &stack_region_size);
    WriteProperty(writer,
                  IntermediateDumpKey::kStackRegionAddress,
                  &stack_region_address);
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kStackRegionData,
                       reinterpret_cast<const void*>(stack_region_address),
                       stack_region_size);

    // Grab extra memory from context.
    CaptureMemoryPointedToByThreadState(writer, thread_state);
  }
}

// static
void InProcessIntermediateDumpHandler::WriteModuleInfo(
    IOSIntermediateDumpWriter* writer) {
#ifndef ARCH_CPU_64_BITS
#error Only 64-bit Mach-O is supported
#endif

  IOSIntermediateDumpWriter::ScopedArray module_array(
      writer, IntermediateDumpKey::kModules);

  task_dyld_info_data_t dyld_info;
  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
  kern_return_t kr = task_info(mach_task_self(),
                               TASK_DYLD_INFO,
                               reinterpret_cast<task_info_t>(&dyld_info),
                               &count);
  if (kr != KERN_SUCCESS) {
    CRASHPAD_RAW_LOG_ERROR(kr, "task_info");
  }

  ScopedVMRead<dyld_all_image_infos> image_infos;
  if (!image_infos.Read(dyld_info.all_image_info_addr)) {
    CRASHPAD_RAW_LOG("Unable to dyld_info.all_image_info_addr");
    return;
  }

  uint32_t image_count = image_infos->infoArrayCount;
  const dyld_image_info* image_array = image_infos->infoArray;
  for (uint32_t image_index = 0; image_index < image_count; ++image_index) {
    IOSIntermediateDumpWriter::ScopedArrayMap modules(writer);
    ScopedVMRead<dyld_image_info> image;
    if (!image.Read(&image_array[image_index])) {
      CRASHPAD_RAW_LOG("Unable to dyld_image_info");
      return;
    }

    WriteProperty(writer,
                  IntermediateDumpKey::kName,
                  image->imageFilePath,
                  strlen(image->imageFilePath));
    uint64_t address = FromPointerCast<uint64_t>(image->imageLoadAddress);
    WriteProperty(writer, IntermediateDumpKey::kAddress, &address);
    WriteProperty(
        writer, IntermediateDumpKey::kTimestamp, &image->imageFileModDate);
    WriteModuleInfoAtAddress(writer, address, false /*is_dyld=false*/);
  }

  {
    IOSIntermediateDumpWriter::ScopedArrayMap modules(writer);
    WriteProperty(writer, IntermediateDumpKey::kName, image_infos->dyldPath);
    uint64_t address =
        FromPointerCast<uint64_t>(image_infos->dyldImageLoadAddress);
    WriteProperty(writer, IntermediateDumpKey::kAddress, &address);
    WriteModuleInfoAtAddress(writer, address, true /*is_dyld=true*/);
  }
}

// static
void InProcessIntermediateDumpHandler::WriteExceptionFromSignal(
    IOSIntermediateDumpWriter* writer,
    const IOSSystemDataCollector& system_data,
    siginfo_t* siginfo,
    ucontext_t* context) {
  IOSIntermediateDumpWriter::ScopedMap signal_exception_map(
      writer, IntermediateDumpKey::kSignalException);

  WriteProperty(writer, IntermediateDumpKey::kSignalNumber, &siginfo->si_signo);
  WriteProperty(writer, IntermediateDumpKey::kSignalCode, &siginfo->si_code);
  WriteProperty(writer, IntermediateDumpKey::kSignalAddress, &siginfo->si_addr);
#if defined(ARCH_CPU_X86_64)
  WriteProperty(
      writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss);
  WriteProperty(
      writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__fs);
#elif defined(ARCH_CPU_ARM64)
  WriteProperty(
      writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss);
  WriteProperty(
      writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__ns);
#else
#error Port to your CPU architecture
#endif

  // Thread ID.
  thread_identifier_info identifier_info;
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kern_return_t kr =
      thread_info(mach_thread_self(),
                  THREAD_IDENTIFIER_INFO,
                  reinterpret_cast<thread_info_t>(&identifier_info),
                  &count);
  if (kr == KERN_SUCCESS) {
    WriteProperty(
        writer, IntermediateDumpKey::kThreadID, &identifier_info.thread_id);
  } else {
    CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::self");
  }
}

// static
void InProcessIntermediateDumpHandler::WriteExceptionFromMachException(
    IOSIntermediateDumpWriter* writer,
    exception_behavior_t behavior,
    thread_t exception_thread,
    exception_type_t exception,
    const mach_exception_data_type_t* code,
    mach_msg_type_number_t code_count,
    thread_state_flavor_t flavor,
    ConstThreadState state,
    mach_msg_type_number_t state_count) {
  IOSIntermediateDumpWriter::ScopedMap mach_exception_map(
      writer, IntermediateDumpKey::kMachException);

  WriteProperty(writer, IntermediateDumpKey::kException, &exception);
  WriteProperty(writer, IntermediateDumpKey::kCodes, code, code_count);
  WriteProperty(writer, IntermediateDumpKey::kFlavor, &flavor);
  WritePropertyBytes(writer,
                     IntermediateDumpKey::kState,
                     state,
                     state_count * sizeof(uint32_t));

  thread_identifier_info identifier_info;
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kern_return_t kr =
      thread_info(exception_thread,
                  THREAD_IDENTIFIER_INFO,
                  reinterpret_cast<thread_info_t>(&identifier_info),
                  &count);
  if (kr == KERN_SUCCESS) {
    WriteProperty(
        writer, IntermediateDumpKey::kThreadID, &identifier_info.thread_id);
  } else {
    CRASHPAD_RAW_LOG_ERROR(kr, "thread_info");
  }
}

// static
void InProcessIntermediateDumpHandler::WriteExceptionFromNSException(
    IOSIntermediateDumpWriter* writer) {
  IOSIntermediateDumpWriter::ScopedMap nsexception_map(
      writer, IntermediateDumpKey::kNSException);

  thread_identifier_info identifier_info;
  mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
  kern_return_t kr =
      thread_info(mach_thread_self(),
                  THREAD_IDENTIFIER_INFO,
                  reinterpret_cast<thread_info_t>(&identifier_info),
                  &count);
  if (kr == KERN_SUCCESS) {
    WriteProperty(
        writer, IntermediateDumpKey::kThreadID, &identifier_info.thread_id);
  } else {
    CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::self");
  }
}

void InProcessIntermediateDumpHandler::WriteModuleInfoAtAddress(
    IOSIntermediateDumpWriter* writer,
    uint64_t address,
    bool is_dyld) {
  ScopedVMRead<mach_header_64> header;
  if (!header.Read(address) || header->magic != MH_MAGIC_64) {
    CRASHPAD_RAW_LOG("Invalid module header");
    return;
  }

  const load_command* command_ptr = reinterpret_cast<const load_command*>(
      reinterpret_cast<const mach_header_64*>(address) + 1);

  ScopedVMRead<load_command> command;
  if (!command.Read(command_ptr)) {
    CRASHPAD_RAW_LOG("Invalid module command");
    return;
  }

  // Make sure that the basic load command structure doesn’t overflow the
  // space allotted for load commands, as well as iterating through ncmds.
  vm_size_t slide = 0;
  const symtab_command* symtab_command = nullptr;
  const dysymtab_command* dysymtab_command = nullptr;
  const segment_command_64* linkedit_seg = nullptr;
  const segment_command_64* text_seg = nullptr;
  for (uint32_t cmd_index = 0, cumulative_cmd_size = 0;
       cmd_index <= header->ncmds && cumulative_cmd_size < header->sizeofcmds;
       ++cmd_index, cumulative_cmd_size += command->cmdsize) {
    if (command->cmd == LC_SEGMENT_64) {
      ScopedVMRead<segment_command_64> segment;
      if (!segment.Read(command_ptr)) {
        CRASHPAD_RAW_LOG("Invalid LC_SEGMENT_64 segment");
        return;
      }
      const segment_command_64* segment_ptr =
          reinterpret_cast<const segment_command_64*>(command_ptr);
      if (strcmp(segment->segname, SEG_TEXT) == 0) {
        text_seg = segment_ptr;
        WriteProperty(writer, IntermediateDumpKey::kSize, &segment->vmsize);
        slide = address - segment->vmaddr;
      } else if (strcmp(segment->segname, SEG_DATA) == 0) {
        WriteDataSegmentAnnotations(writer, segment_ptr, slide);
      } else if (strcmp(segment->segname, SEG_LINKEDIT) == 0) {
        linkedit_seg = segment_ptr;
      }
    } else if (command->cmd == LC_SYMTAB) {
      symtab_command =
          reinterpret_cast<const struct symtab_command*>(command_ptr);
    } else if (command->cmd == LC_DYSYMTAB) {
      dysymtab_command =
          reinterpret_cast<const struct dysymtab_command*>(command_ptr);
    } else if (command->cmd == LC_ID_DYLIB) {
      ScopedVMRead<dylib_command> dylib;
      if (!dylib.Read(command_ptr)) {
        CRASHPAD_RAW_LOG("Invalid LC_ID_DYLIB segment");
        return;
      }
      WriteProperty(writer,
                    IntermediateDumpKey::kDylibCurrentVersion,
                    &dylib->dylib.current_version);
    } else if (command->cmd == LC_SOURCE_VERSION) {
      ScopedVMRead<source_version_command> source_version;
      if (!source_version.Read(command_ptr)) {
        CRASHPAD_RAW_LOG("Invalid LC_SOURCE_VERSION segment");
        return;
      }
      WriteProperty(writer,
                    IntermediateDumpKey::kSourceVersion,
                    &source_version->version);
    } else if (command->cmd == LC_UUID) {
      ScopedVMRead<uuid_command> uuid;
      if (!uuid.Read(command_ptr)) {
        CRASHPAD_RAW_LOG("Invalid LC_UUID segment");
        return;
      }
      WriteProperty(writer, IntermediateDumpKey::kUUID, &uuid->uuid);
    }

    command_ptr = reinterpret_cast<const load_command*>(
        reinterpret_cast<const uint8_t*>(command_ptr) + command->cmdsize);
    if (!command.Read(command_ptr)) {
      CRASHPAD_RAW_LOG("Invalid module command");
      return;
    }
  }

  WriteProperty(writer, IntermediateDumpKey::kFileType, &header->filetype);

  if (is_dyld && header->filetype == MH_DYLINKER) {
    WriteDyldErrorStringAnnotation(writer,
                                   address,
                                   symtab_command,
                                   dysymtab_command,
                                   text_seg,
                                   linkedit_seg,
                                   slide);
  }
}

void InProcessIntermediateDumpHandler::WriteDataSegmentAnnotations(
    IOSIntermediateDumpWriter* writer,
    const segment_command_64* segment_ptr,
    vm_size_t slide) {
  ScopedVMRead<segment_command_64> segment;
  if (!segment.Read(segment_ptr)) {
    CRASHPAD_RAW_LOG("Unable to read SEG_DATA.");
    return;
  }
  const section_64* section_ptr = reinterpret_cast<const section_64*>(
      reinterpret_cast<uint64_t>(segment_ptr) + sizeof(segment_command_64));
  for (uint32_t sect_index = 0; sect_index <= segment->nsects; ++sect_index) {
    ScopedVMRead<section_64> section;
    if (!section.Read(section_ptr)) {
      CRASHPAD_RAW_LOG("Unable to read SEG_DATA section.");
      return;
    }
    if (strcmp(section->sectname, "crashpad_info") == 0) {
      ScopedVMRead<CrashpadInfo> crashpad_info;
      if (crashpad_info.Read(section->addr + slide) &&
          crashpad_info->size() == sizeof(CrashpadInfo) &&
          crashpad_info->signature() == CrashpadInfo::kSignature &&
          crashpad_info->version() == 1) {
        WriteCrashpadAnnotationsList(writer, crashpad_info.get());
        WriteCrashpadSimpleAnnotationsDictionary(writer, crashpad_info.get());
      }
    } else if (strcmp(section->sectname, "__crash_info") == 0) {
      ScopedVMRead<crashreporter_annotations_t> crash_info;
      if (!crash_info.Read(section->addr + slide) ||
          (crash_info->version != 4 && crash_info->version != 5)) {
        continue;
      }
      WriteAppleCrashReporterAnnotations(writer, crash_info.get());
    }
    section_ptr = reinterpret_cast<const section_64*>(
        reinterpret_cast<uint64_t>(section_ptr) + sizeof(section_64));
  }
}

void InProcessIntermediateDumpHandler::WriteCrashpadAnnotationsList(
    IOSIntermediateDumpWriter* writer,
    CrashpadInfo* crashpad_info) {
  if (!crashpad_info->annotations_list()) {
    return;
  }
  ScopedVMRead<AnnotationList> annotation_list;
  if (!annotation_list.Read(crashpad_info->annotations_list())) {
    CRASHPAD_RAW_LOG("Unable to read annotations list object");
    return;
  }

  IOSIntermediateDumpWriter::ScopedArray annotations_array(
      writer, IntermediateDumpKey::kAnnotationObjects);
  ScopedVMRead<Annotation> current;
  if (!current.Read(annotation_list->head())) {
    CRASHPAD_RAW_LOG("Unable to read annotation");
    return;
  }

  for (size_t index = 0;
       current->link_node() != annotation_list.get()->tail_pointer() &&
       index < kMaxNumberOfAnnotations;
       ++index) {
    ScopedVMRead<Annotation> node;
    if (!node.Read(current->link_node())) {
      CRASHPAD_RAW_LOG("Unable to read annotation");
      return;
    }
    current.Read(current->link_node());

    if (node->size() == 0)
      continue;

    if (node->size() > Annotation::kValueMaxSize) {
      CRASHPAD_RAW_LOG("Incorrect annotation length");
      continue;
    }

    IOSIntermediateDumpWriter::ScopedArrayMap annotation_map(writer);
    const size_t name_len = strnlen(reinterpret_cast<const char*>(node->name()),
                                    Annotation::kNameMaxLength);
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationName,
                       reinterpret_cast<const void*>(node->name()),
                       name_len);
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationValue,
                       reinterpret_cast<const void*>(node->value()),
                       node->size());
    Annotation::Type type = node->type();
    WritePropertyBytes(writer,
                       IntermediateDumpKey::kAnnotationType,
                       reinterpret_cast<const void*>(&type),
                       sizeof(type));
  }
}

}  // namespace internal
}  // namespace crashpad
