|  | // Copyright 2014 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. | 
|  |  | 
|  | #ifndef CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_ | 
|  | #define CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_ | 
|  |  | 
|  | #include <stdint.h> | 
|  | #include <sys/types.h> | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "util/numeric/checked_range.h" | 
|  |  | 
|  | namespace crashpad { | 
|  |  | 
|  | //! \brief An abstract interface to a snapshot representing a region of memory | 
|  | //!     present in a snapshot process. | 
|  | class MemorySnapshot { | 
|  | public: | 
|  | //! \brief An interface that MemorySnapshot clients must implement in order to | 
|  | //!     receive memory snapshot data. | 
|  | //! | 
|  | //! This callback-based model frees MemorySnapshot implementations from having | 
|  | //! to deal with memory region ownership problems. When a memory snapshot’s | 
|  | //! data is read, it will be passed to a delegate method. | 
|  | class Delegate { | 
|  | public: | 
|  | virtual ~Delegate() {} | 
|  |  | 
|  | //! \brief Called by MemorySnapshot::Read() to provide data requested by a | 
|  | //!     call to that method. | 
|  | //! | 
|  | //! \param[in] data A pointer to the data that was read. The callee does not | 
|  | //!     take ownership of this data. This data is only valid for the | 
|  | //!     duration of the call to this method. This parameter may be `nullptr` | 
|  | //!     if \a size is `0`. | 
|  | //! \param[in] size The size of the data that was read. | 
|  | //! | 
|  | //! \return `true` on success, `false` on failure. MemoryDelegate::Read() | 
|  | //!     will use this as its own return value. | 
|  | virtual bool MemorySnapshotDelegateRead(void* data, size_t size) = 0; | 
|  | }; | 
|  |  | 
|  | virtual ~MemorySnapshot() {} | 
|  |  | 
|  | //! \brief The base address of the memory snapshot in the snapshot process’ | 
|  | //!     address space. | 
|  | virtual uint64_t Address() const = 0; | 
|  |  | 
|  | //! \brief The size of the memory snapshot. | 
|  | virtual size_t Size() const = 0; | 
|  |  | 
|  | //! \brief Calls Delegate::MemorySnapshotDelegateRead(), providing it with | 
|  | //!     the memory snapshot’s data. | 
|  | //! | 
|  | //! Implementations do not necessarily read the memory snapshot data prior to | 
|  | //! this method being called. Memory snapshot data may be loaded lazily and | 
|  | //! may be discarded after being passed to the delegate. This provides clean | 
|  | //! memory management without burdening a snapshot implementation with the | 
|  | //! requirement that it track all memory region data simultaneously. | 
|  | //! | 
|  | //! \return `false` on failure, otherwise, the return value of | 
|  | //!     Delegate::MemorySnapshotDelegateRead(), which should be `true` on | 
|  | //!     success and `false` on failure. | 
|  | virtual bool Read(Delegate* delegate) const = 0; | 
|  |  | 
|  | //! \brief Creates a new MemorySnapshot based on merging this one with \a | 
|  | //!     other. | 
|  | //! | 
|  | //! The ranges described by the two snapshots must either overlap or abut, and | 
|  | //! must be of the same concrete type. | 
|  | //! | 
|  | //! \return A newly allocated MemorySnapshot representing the merged range, or | 
|  | //!     `nullptr` with an error logged. | 
|  | virtual const MemorySnapshot* MergeWithOtherSnapshot( | 
|  | const MemorySnapshot* other) const = 0; | 
|  | }; | 
|  |  | 
|  | //! \brief Given two memory snapshots, checks if they're overlapping or | 
|  | //!     abutting, and if so, returns the result of merging the two ranges. | 
|  | //! | 
|  | //! This function is useful to implement | 
|  | //! MemorySnapshot::MergeWithOtherSnapshot(). | 
|  | //! | 
|  | //! \param[in] a The first range. Must have Size() > 0. | 
|  | //! \param[in] b The second range. Must have Size() > 0. | 
|  | //! \param[out] merged The resulting merged range. May be `nullptr` if only a | 
|  | //!     characterization of the ranges is desired. | 
|  | //! | 
|  | //! \return `true` if the input ranges overlap or abut, with \a merged filled | 
|  | //!     out, otherwise, `false` with an error logged if \a log is `true`. | 
|  | bool LoggingDetermineMergedRange(const MemorySnapshot* a, | 
|  | const MemorySnapshot* b, | 
|  | CheckedRange<uint64_t, size_t>* merged); | 
|  |  | 
|  | //! \brief The same as LoggingDetermineMergedRange but with no errors logged. | 
|  | //! | 
|  | //! \sa LoggingDetermineMergedRange | 
|  | bool DetermineMergedRange(const MemorySnapshot* a, | 
|  | const MemorySnapshot* b, | 
|  | CheckedRange<uint64_t, size_t>* merged); | 
|  |  | 
|  | }  // namespace crashpad | 
|  |  | 
|  | #endif  // CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_ |