R_REG(3)

R_REG β€” the radare2 register management library πŸ’…βœ¨

okay bestie, welcome to r_reg(3) from the Library Functions Manual, and no cap this one is the glow-up of register handling in radare2. grab a strawberry πŸ“ and let's get into it.


SYNOPSIS

#include <r_reg.h>

DESCRIPTION

The r_reg API is a portable register model that gets used all over the place β€” analysis, emulation, debugging, the whole friend group. It hands you:

  • typed register items ✨
  • aliases, aka roles like PC/SP πŸ‘‘
  • an arena you can push/pop register snapshots on πŸŽ€
  • helpers to read/write register values in all the different representations πŸ¦‹

it's giving "one library to hold them all" fr fr.


INITIALIZATION

before you do literally anything, you need a register context. that context is the main character β€” it owns the profiles, the arena, and the register list. typical callers are the analysis engine and the debugger, and they each keep their own separate register contexts (no sharing bestie, they have their own vibes).

  • RReg * r_reg_new(void) β€” creates a new register context 🫢
  • void r_reg_free(RReg *reg) β€” frees all the resources associated with the register context. bye bestie, you ate πŸ’€

PROFILES

profiles are how the library knows which registers exist, how big they are, and what roles they play. they get loaded from strings or from files, and analysis + ESIL use them to map register names and roles. lowkey essential.

  • bool r_reg_set_profile(RReg *reg, const char *profile) β€” loads a profile from a file path πŸ“
  • bool r_reg_set_profile_string(RReg *reg, const char *profile) β€” loads a profile straight from a string buffer 🌸
  • char * r_reg_profile_to_cc(RReg *reg) β€” dumps the profile as C-compatible declarations (tools use this one) ✨

REGISTER ACCESS

register names and roles are the primary API for callers who just need scalar accesses. if you're out here needing float/double/packed values, go use the typed APIs instead (they're in the next section, don't worry).

  • RRegItem * r_reg_get(RReg *reg, const char *name, int type) β€” retrieve a register item by name; pass type as -1 to ignore type πŸ’…
  • ut64 r_reg_getv(RReg *reg, const char *name) β€” get a 64-bit value for register name. this is the most common convenience function in the entire codebase (analysis, esil, debug all call it, it's iconic) πŸ”₯
  • bool r_reg_setv(RReg *reg, const char *name, ut64 val) β€” set a 64-bit value for register name. ESIL and a bunch of other subsystems call this to do register writes 🫢
  • ut64 r_reg_get_value_by_role(RReg *reg, RRegAlias alias) β€” get the value of a register given its alias role (for example R_REG_ALIAS_PC). obsessed with this one when code works with roles instead of concrete names πŸ‘‘

REGISTER VALUES

when you're dealing with non-integer registers (floating point, long double) or you're messing with sub-parts of registers, this is the section for you. typed getters/setters, let's gooo.

  • ut64 r_reg_get_value(RReg *reg, RRegItem *item) β€” return the integer value of a register item
  • bool r_reg_set_value(RReg *reg, RRegItem *item, ut64 value) β€” set the integer value for a register item
  • float r_reg_get_float(RReg *reg, RRegItem *item) β€” get a float value from the register item when applicable
  • double r_reg_get_double(RReg *reg, RRegItem *item) β€” get a double value from the register item when applicable
  • long double r_reg_get_longdouble(RReg *reg, RRegItem *item) β€” get a long double value (so useful for extended FP registers) 🌈
  • bool r_reg_set_longdouble(RReg *reg, RRegItem *item, long double value) β€” set a long double value in the register item

REGISTER LISTS

you can iterate registers by type β€” GPR, FPU, vector, flags. this is commonly used to serialize register state, or when you're emitting a register snapshot. very "packing my bags for a trip" energy 🧚

  • RList * r_reg_get_list(RReg *reg, int type) β€” return a list of RRegItem for the requested type
  • RRegItem * r_reg_index_get(RReg *reg, int idx) β€” get a register item by absolute index

ALIASES

aliases map roles to concrete register names, per profile β€” for example PC -> rip on x86_64. use these whenever your code should be architecture agnostic, because hard-coded register names are so not the vibe.

  • bool r_reg_alias_setname(RReg *reg, RRegAlias alias, const char *name) β€” assign a name to an alias role
  • const char * r_reg_alias_getname(RReg *reg, RRegAlias alias) β€” return the concrete register name for the alias
  • const char * r_reg_alias_tostring(RRegAlias alias) β€” return a textual representation of the alias role ✨

ARENA MANAGEMENT

the arena is literally the moment. it lets you temporarily change registers and restore them later, and it is heavily used by analysis passes and by debugger backends when they want to peek at or modify registers without permanently changing the user-visible state. peek, don't keep 🫢

  • int r_reg_arena_push(RReg *reg) β€” push the current register snapshot onto the arena stack and return the new stack depth
  • void r_reg_arena_pop(RReg *reg) β€” pop the last snapshot and restore register values to that state πŸŽ€
  • ut8 * r_reg_get_bytes(RReg *reg, int type, int *size) β€” get a packed byte representation of registers of type (so good for copying to a target or computing diffs)
  • bool r_reg_set_bytes(RReg *reg, int type, const ut8 *buf, const int len) β€” set the bytes for registers of type from a buffer

CONDITIONS

these helpers convert CPU flags into boolean conditions (equal, greater, etc.) and back again. ESIL and analysis use them to evaluate branching conditions, so yeah, kind of a big deal.

  • bool r_reg_cond(RReg *r, int type) β€” evaluate a condition represented by type using the current register flags. for example, R_REG_COND_EQ checks the zero flag πŸ’…
  • RRegFlags * r_reg_cond_retrieve(RReg *r, RRegFlags *f) β€” fill the RRegFlags structure from the current register flags (fields like zero, carry, sign) so callers can inspect or modify them
  • void r_reg_cond_apply(RReg *r, RRegFlags *f) β€” apply a RRegFlags structure back into the register context

USAGE NOTES

the typical usage patterns you'll find in the codebase, bestie, are literally these:

  • when analyzing or emulating instructions: push the arena, modify registers (for example set PC to the next address), run the evaluation (ESIL or analysis) and pop the arena to restore the original state. files that follow this pattern include libr/core/canal.c and libr/core/cmd_debug.inc.c 🌸
  • use r_reg_getv/r_reg_setv for most reads/writes, because they're simple and fast wrappers over the typed APIs. ESIL registers also call r_reg_setv through .reg_write hooks πŸ”₯
  • when code needs to be architecture-agnostic, prefer r_reg_get_value_by_role or r_reg_alias_getname instead of hard-coded register names πŸ‘‘

EXAMPLES

this example shows a common pattern used across radare2: read PC/SP, temporarily modify registers to simulate an instruction, and restore the previous state. iconic behaviour, no notes.

// obtain the register context from core
RReg *reg = core->anal->reg;
// read program counter and stack pointer
ut64 pc = r_reg_getv (reg, "PC");
ut64 sp = r_reg_getv (reg, "SP");
// create a temporary snapshot
r_reg_arena_push (reg);
// modify registers for analysis/emulation
r_reg_setv (reg, "PC", pc + insn_size);
// run evaluation or analysis using modified registers...
// restore previous register state
r_reg_arena_pop (reg);

another practical example β€” retrieving an alias value (role based):

// get program counter regardless of arch-specific name
ut64 pc = r_reg_get_value_by_role (reg, R_REG_ALIAS_PC);

ESIL integration note:

// ESIL uses r_reg_setv as the register write callback:
// in libr/esil/esil.c: .reg_write = (REsilRegWrite)r_reg_setv
// so using r_reg_setv keeps behavior consistent with ESIL expectations.
ngl that last one is the "iykyk" of this whole page. use r_reg_setv, stay consistent with ESIL, live your truth πŸ’œ

SEE ALSO


and that's the whole page bestie, you ate that πŸ’…βœ¨ this one shipped as part of Debian, dated September 20, 2025 β€” go forth and manage some registers, you absolute icon πŸ‘‘πŸ¦‹πŸŽ€

πŸ“¦ where this page comes from