mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-23 01:33:06 +00:00
04d2dee964
There's a lot more context here that we should write down. It's also
worth noting that it appears that GDB always zero fills the range
between p_filesz and p_memsz, so if we end up having any other issues
because of this, we might have to concede and go back to the behavior
before commit 02912ca7d0
("libdrgn: fix handling of p_filesz < p_memsz
in core dumps").
Signed-off-by: Omar Sandoval <osandov@osandov.com>
127 lines
3.6 KiB
C
127 lines
3.6 KiB
C
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
// SPDX-License-Identifier: GPL-3.0-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.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);
|
|
|
|
/** 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 */
|