1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
// SPDX-License-Identifier: LGPL-2.1-or-later
/**
* @file
*
* Memory reading interface.
*
* See @ref MemoryReader.
*/
#ifndef DRGN_MEMORY_READER_H
#define DRGN_MEMORY_READER_H
#include "binary_search_tree.h"
#include "drgn_internal.h"
/**
* @ingroup Internals
*
* @defgroup MemoryReader Memory reader
*
* Memory reading interface.
*
* @ref drgn_memory_reader provides a common interface for registering regions
* of memory in a program and reading from memory.
*
* @ref drgn_memory_reader does not have a notion of the maximum address or
* address overflow/wrap-around. Those must be handled at a higher layer.
*
* @{
*/
DEFINE_BINARY_SEARCH_TREE_TYPE(drgn_memory_segment_tree,
struct drgn_memory_segment);
/**
* Memory reader.
*
* A memory reader maps the segments of memory in an address space to callbacks
* which can be used to read memory from those segments.
*/
struct drgn_memory_reader {
/** Virtual memory segments. */
struct drgn_memory_segment_tree virtual_segments;
/** Physical memory segments. */
struct drgn_memory_segment_tree physical_segments;
};
/**
* Initialize a @ref drgn_memory_reader.
*
* The reader is initialized with no segments.
*/
void drgn_memory_reader_init(struct drgn_memory_reader *reader);
/** Deinitialize a @ref drgn_memory_reader. */
void drgn_memory_reader_deinit(struct drgn_memory_reader *reader);
/** Remove all segments from a @ref drgn_memory_reader. */
void drgn_memory_reader_clear(struct drgn_memory_reader *reader);
/** Remove all virtual memory segments from a @ref drgn_memory_reader. */
void drgn_memory_reader_clear_virtual(struct drgn_memory_reader *reader);
/** Return whether a @ref drgn_memory_reader has no segments. */
bool drgn_memory_reader_empty(struct drgn_memory_reader *reader);
/**
* Add a segment to a @ref drgn_memory_reader.
*
* @param[in] reader Memory reader.
* @param[in] min_address Start address (inclusive).
* @param[in] max_address End address (inclusive). Must be `>= min_address`.
* @param[in] read_fn Callback to read from segment.
* @param[in] arg Argument to pass to @p read_fn.
* @param[in] physical Whether to add a physical memory segment.
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *
drgn_memory_reader_add_segment(struct drgn_memory_reader *reader,
uint64_t min_address, uint64_t max_address,
drgn_memory_read_fn read_fn, void *arg,
bool physical);
/**
* Read from a @ref drgn_memory_reader.
*
* @param[in] reader Memory reader.
* @param[out] buf Buffer to read into.
* @param[in] address Starting address in memory to read.
* @param[in] count Number of bytes to read. `address + count - 1` must be
* `<= UINT64_MAX`
* @param[in] physical Whether @c address is physical.
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *drgn_memory_reader_read(struct drgn_memory_reader *reader,
void *buf, uint64_t address,
size_t count, bool physical);
/** Argument for @ref drgn_read_memory_file(). */
struct drgn_memory_file_segment {
/** Offset in the file where the segment starts. */
uint64_t file_offset;
/**
* Size of the segment in the file. This may be less than the size of
* the segment in memory.
*/
uint64_t file_size;
/** File descriptor. */
int fd;
/**
* If @c true, EIO is treated as a fault. Otherwise, it is treated as an
* OS error.
*/
bool eio_is_fault;
/**
* If @c true, reads between @ref file_size and the size of the segment
* in memory will be returned as zeroes. Otherwise, such reads will
* result in a fault.
*/
bool zerofill;
};
/** @ref drgn_memory_read_fn which reads from a file. */
struct drgn_error *drgn_read_memory_file(void *buf, uint64_t address,
size_t count, uint64_t offset,
void *arg, bool physical);
/** @} */
#endif /* DRGN_MEMORY_READER_H */
|