#26783·radare2

Follow up RIODescInfo consolidation: target info, size and IO capabilities

Author: trufaeCreated Sep 22, 2026Updated Sep 27, 2026

Follow-up to #26121, which consolidates device/debugger flags and listener detection in RIODescInfo.

The goal is to remove duplicate callbacks and query wrappers, simplify consumers, and keep descriptor information cheap to obtain. This is a candidate inventory for discussion, not a proposal to add every field.

listener is the clearest additional consolidation: it already had a separate plugin callback and r_io_is_listener() wrapper. It is being handled in #26121; the remaining options are tracked here.

The strongest candidates for consolidating existing queries:

Candidate What it provides Main consideration
listener Whether this descriptor is accepting connections Handled in #26121 by removing the separate callback and wrapper.
pid, tid Process and thread associated with the descriptor Define whether these mean attached or currently selected; existing plugins differ.
baddr Main executable's load base Distinguish it from the start of an IO mapping.
size Length of the exposed data, including device capacity in bytes Must distinguish unknown size from an empty descriptor and an address-space limit.
size_kind or size validity Exact, unknown, or unbounded size Could replace ambiguous size sentinels.
seek_caps Supported positioning: absolute, relative, end, holes More useful for IO decisions than using chrdev as a proxy for seek behavior.
caps Read, write, resize, extend, accept capabilities Describe this descriptor's capabilities. A callback existing does not guarantee the operation works.
Resource classification File, block device, character device, stream, memory Keep independent properties such as isdbg separate; a remote debugger can also expose memory.

Device geometry and transfer constraints are also eligible, provided something consumes them:

Candidate What it enables Main consideration
logical_block_size Correct sector addressing and minimum device access units Separate from total device capacity.
physical_block_size Better alignment of device writes Different from logical sector size.
Read/write offset alignment Alignment of the requested address Read and write requirements can differ.
Read/write length alignment Valid transfer lengths Separate from address alignment.
Buffer alignment Requirements on the caller's memory buffer Only expose restrictions the plugin passes through to callers.
min_io, preferred_io Minimum and efficient transfer sizes Required constraints and performance hints need distinct meanings.
max_read, max_write Generic chunking for remote or device IO Report usable payload sizes, not raw protocol packet sizes.
page_size Target memory page granularity Target page size can differ from the host's.
allocation_granularity Alignment for allocation or mapping Not necessarily the page size.
erase_block_size, write granularity Flash programming constraints Useful for device backends; probably a separate feature.
Address bounds Lowest/highest address the descriptor can represent Bounds do not establish that every address inside is readable.
addrbytes / address unit Conversion between addresses and byte counts Would require reconciling the existing RIO.addrbytes setting.
Address-space kind File offsets, process virtual memory, physical memory, registers Useful only if generic code makes a concrete decision from it.
Sparse/hole behavior Whether gaps exist and how reads of gaps behave Actual extents need a separate query or iterator.

Other plausible options, with weaker justification for the initial consolidation:

Candidate Potential use Why to be selective
volatile / externally mutable Cache invalidation decisions for live memory or changing resources Ordinary files can change externally too; define a precise guarantee.
Read/write side-effect flags Avoid repeated reads of device registers or MMIO Often belongs to individual ranges rather than the whole descriptor.
Growing / fixed-length / snapshot properties Decide whether cached size remains useful Distinct from whether callers may resize it.
Native FD or handle Polling, OS integration, zero-copy operations Needs a tagged, borrowed handle; it is different from r2's descriptor ID.
isatty Terminal-specific behavior Character device alone does not imply terminal.
Nonblocking / append mode Explain effective IO semantics Describe the exposed descriptor, including any buffering performed by the plugin.
Transport / remote status Diagnostics and connection presentation Prefer actual capabilities over decisions based solely on "remote".
Connection state, EOF, readiness, available bytes Stream handling These become stale immediately; explicit status/poll queries usually fit better.
Current offset Replace queries that use seek-to-current Existing global and plugin-local offsets need consistent semantics first.
Backing descriptor and offset Describe slices and layered resources Compression and transformations cannot always be represented as a simple offset.
File identity, timestamps, allocated size Detect replacement/modification; describe sparse storage This starts becoming a separate stat API.
Target executable path Avoid textual debugger commands for executable discovery String ownership and remote-query cost complicate a small value struct.
Architecture, bits, endian, OS hints Initialize target configuration from a backend Keep ownership with the appropriate architecture/debug layer; avoid conflicting copies.
Generation counter Tell consumers when cached information changed Only useful with a defined update/invalidation contract.

Avoid duplicating fd, permissions, name, URI, plugin identity, or configuration already accessible through RIODesc. Registers, stop reasons, thread/module lists, and memory maps belong in their existing debug/map APIs.

The limiting factor is query cost. r_io_desc_info() is called during ordinary reads and writes in libr/io/io_plugin.c. Querying sysgdb's PID sends a debugger command; querying descriptor size can perform three seeks. Those operations cannot become an automatic consequence of checking a flag.

The suggested priority after listener consolidation is PID/TID/base consolidation. Seek capabilities are the strongest additional behavioral improvement. Size and geometry deserve an explicit query-cost contract first. Optional values also need validity indicators: zero is a valid size or base address, and "unknown" must remain distinguishable.