Commit 81b700e3 authored by Roland McGrath's avatar Roland McGrath Committed by Petr Hosek
Browse files

[sanitizer_common] Implement MemoryMappingLayout for Fuchsia

This is needed to port lsan to Fuchsia.

Patch By: mcgrathr

Differential Revision: https://reviews.llvm.org/D72886
parent 303fddee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ set(SANITIZER_SOURCES_NOTERMINATION
  sanitizer_printf.cpp
  sanitizer_procmaps_common.cpp
  sanitizer_procmaps_bsd.cpp
  sanitizer_procmaps_fuchsia.cpp
  sanitizer_procmaps_linux.cpp
  sanitizer_procmaps_mac.cpp
  sanitizer_procmaps_solaris.cpp
+6 −0
Original line number Diff line number Diff line
@@ -18,12 +18,18 @@
#include "sanitizer_common.h"

#include <zircon/sanitizer.h>
#include <zircon/syscalls/object.h>

namespace __sanitizer {

extern uptr MainThreadStackBase, MainThreadStackSize;
extern sanitizer_shadow_bounds_t ShadowBounds;

struct MemoryMappingLayoutData {
  InternalMmapVector<zx_info_maps_t> data;
  size_t current;  // Current index into the vector.
};

}  // namespace __sanitizer

#endif  // SANITIZER_FUCHSIA
+4 −3
Original line number Diff line number Diff line
@@ -16,17 +16,18 @@
#include "sanitizer_platform.h"

#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
    SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_SOLARIS
    SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_SOLARIS ||  \
    SANITIZER_FUCHSIA

#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_fuchsia.h"
#include "sanitizer_linux.h"
#include "sanitizer_mac.h"
#include "sanitizer_mutex.h"

namespace __sanitizer {


// Memory protection masks.
static const uptr kProtectionRead = 1;
static const uptr kProtectionWrite = 2;
+80 −0
Original line number Diff line number Diff line
//===-- sanitizer_procmaps_fuchsia.cpp
//----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Information about the process mappings (Fuchsia-specific parts).
//===----------------------------------------------------------------------===//

#include "sanitizer_platform.h"
#if SANITIZER_FUCHSIA
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include "sanitizer_common.h"
#include "sanitizer_procmaps.h"

namespace __sanitizer {

// The cache flag is ignored on Fuchsia because a process can always get this
// information via its process-self handle.
MemoryMappingLayout::MemoryMappingLayout(bool) { Reset(); }

void MemoryMappingLayout::Reset() {
  data_.data.clear();
  data_.current = 0;

  size_t count;
  zx_status_t status = _zx_object_get_info(
      _zx_process_self(), ZX_INFO_PROCESS_MAPS, nullptr, 0, nullptr, &count);
  if (status != ZX_OK) {
    return;
  }

  size_t filled;
  do {
    data_.data.resize(count);
    status = _zx_object_get_info(
        _zx_process_self(), ZX_INFO_PROCESS_MAPS, data_.data.data(),
        count * sizeof(zx_info_maps_t), &filled, &count);
    if (status != ZX_OK) {
      data_.data.clear();
      return;
    }
  } while (filled < count);
}

MemoryMappingLayout::~MemoryMappingLayout() {}

bool MemoryMappingLayout::Error() const { return data_.data.empty(); }

bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
  while (data_.current < data_.data.size()) {
    const auto &entry = data_.data[data_.current++];
    if (entry.type == ZX_INFO_MAPS_TYPE_MAPPING) {
      segment->start = entry.base;
      segment->end = entry.base + entry.size;
      segment->offset = entry.u.mapping.vmo_offset;
      const auto flags = entry.u.mapping.mmu_flags;
      segment->protection =
          ((flags & ZX_VM_PERM_READ) ? kProtectionRead : 0) |
          ((flags & ZX_VM_PERM_WRITE) ? kProtectionWrite : 0) |
          ((flags & ZX_VM_PERM_EXECUTE) ? kProtectionExecute : 0);
      if (segment->filename && segment->filename_size > 0) {
        uptr len = Min(sizeof(entry.name), segment->filename_size) - 1;
        internal_strncpy(segment->filename, entry.name, len);
        segment->filename[len] = 0;
      }
      return true;
    }
  }
  return false;
}

}  // namespace __sanitizer

#endif  // SANITIZER_FUCHSIA