Provided by: radare2_6.0.7+ds-1_amd64 bug

NAME

       r_esil — radare2 ESIL (Evaluable Strings Intermediate Language) library

SYNOPSIS

       #include <r_esil.h>

DESCRIPTION

       The  r_esil  library  implements  ESIL,  a  stack-based  intermediate language for symbolic execution and
       emulation in radare2. ESIL  allows  for  architecture-independent  representation  of  CPU  instructions,
       enabling analysis, emulation, and symbolic computation across different architectures.

       The  core  structure  is  REsil,  which  maintains  a  stack, registers, memory interfaces, and operation
       handlers for executing ESIL expressions.

INITIALIZATION

       Create and configure ESIL contexts and  their  runtime  dependencies  so  they  are  ready  for  parsing,
       execution and interaction with radare2 analysis and I/O layers.

       REsil * r_esil_new(int stacksize, int iotrap, unsigned int addrsize)

       Creates a new ESIL instance with the specified stack size, I/O trap settings, and address size.

       bool  r_esil_init(REsil  *esil,  int  stacksize,  bool  iotrap, ut32 addrsize, REsilRegInterface *reg_if,
       REsilMemInterface *mem_if)

       Initializes an existing ESIL structure with register and memory interfaces.

       void r_esil_free(REsil *esil)

       Frees all resources associated with the ESIL instance.

PARSING AND EXECUTION

       Convert ESIL strings into runtime operations and drive the ESIL virtual machine to  evaluate  or  emulate
       instruction semantics; these routines are the entry points for feeding ESIL expressions into the engine.

       bool r_esil_parse(REsil *esil, const char *str)

       Parses and executes an ESIL expression string.

       bool r_esil_runword(REsil *esil, const char *word)

       Executes a single ESIL operation word.

STACK OPERATIONS

       Manipulate  the  ESIL  evaluation  stack  directly  when constructing or inspecting temporary values used
       during expression evaluation.

       bool r_esil_push(REsil *esil, const char *str)

       Pushes a value or expression onto the ESIL stack.

       char * r_esil_pop(REsil *esil)

       Pops the top value from the ESIL stack.

       bool r_esil_pushnum(REsil *esil, ut64 num)

       Pushes a numeric value onto the stack.

REGISTER ACCESS

       Query and modify the register state the ESIL engine uses; these functions bridge  ESIL  and  the  radare2
       register  model  (RReg)  and  are used extensively by core components to read/write CPU state silently or
       with callbacks.

       bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *size)

       Reads the value of a register.

       bool r_esil_reg_write(REsil *esil, const char *name, ut64 val)

       Writes a value to a register.

MEMORY ACCESS

       Read from and write into the memory backing used  by  ESIL.  Implementations  may  use  the  radare2  I/O
       bindings so ESIL memory operations map to the analyzed process or file backend.

       bool r_esil_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len)

       Reads memory at the specified address.

       bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len)

       Writes data to memory at the specified address.

OPERATIONS

       Register,  query  or  remove  ESIL  operation  handlers.  Custom operations can be installed to extend or
       override built-in ESIL semantics at runtime.

       bool r_esil_set_op(REsil *esil, const char *op, REsilOpCb code, ut32 push, ut32  pop,  ut32  type,  const
       char *info)

       Defines a custom ESIL operation.

       REsilOp * r_esil_get_op(REsil *esil, const char *op)

       Retrieves information about an ESIL operation.

PLUGINS

       Manage architecture or feature plugins which provide arch-specific ESIL initialization, helpers and extra
       op handlers; activating a plugin hooks it into the ESIL instance used by analysis and emulation.

       bool r_esil_plugin_add(REsil *esil, REsilPlugin *plugin)

       Adds an ESIL plugin for architecture-specific operations.

       bool r_esil_plugin_activate(REsil *esil, const char *name)

       Activates an ESIL plugin by name.

TRACING

       Record  and  inspect  execution  traces  produced  while ESIL evaluates expressions.  The trace subsystem
       captures ops, memory and register accesses to aid analysis and debugging of emulation sessions.

       REsilTrace * r_esil_trace_new(REsil *esil)

       Creates a new trace for recording ESIL execution.

       void r_esil_trace_op(REsil *esil, struct r_anal_op_t *op)

       Traces the execution of an analysis operation.

INTERRUPTS AND SYSCALLS

       Install handlers or trigger software interrupts and syscalls  from  ESIL;  these  hooks  allow  embedding
       environment-specific behavior (e.g. syscalls emulation) into ESIL evaluation.

       bool r_esil_set_interrupt(REsil *esil, ut32 intr_num, REsilHandlerCB cb, void *user)

       Sets a handler for a specific interrupt number.

       bool r_esil_set_syscall(REsil *esil, ut32 sysc_num, REsilHandlerCB cb, void *user)

       Sets a handler for a specific syscall number.

COMPILER

       Provide utilities to translate or compile ESIL expressions into other forms such as C-like code (esil->c)
       and to reuse ESIL parsing logic outside a running engine.

       REsilCompiler * r_esil_compiler_new(void)

       Creates a new ESIL compiler for converting expressions.

       bool r_esil_compiler_parse(REsilCompiler *ec, const char *expr)

       Parses an ESIL expression into the compiler.

EXAMPLES

       Show how to wire ESIL to minimal register and memory callbacks to evaluate an expression and retrieve the
       result,  plus  a  compact  low-level  example  that  demonstrates  direct  stack  manipulation and simple
       expression-level debugging.

       Full example: set up register and memory callbacks, evaluate an ESIL string, and read the result:

             /* Simple register callbacks that only handle "rax" and "rbx" for demo */
             static bool my_is_reg(void *user, const char *name) {
                 return !strcmp(name, "rax") || !strcmp(name, "rbx");
             }
             static bool my_reg_read(void *user, const char *name, ut64 *res) {
                 if (!strcmp(name, "rax")) { *res = 0x10; return true; }
                 if (!strcmp(name, "rbx")) { *res = 0x20; return true; }
                 return false;
             }
             static bool my_reg_write(void *user, const char *name, ut64 val) {
                 /* store val into your backend */
                 (void)user; (void)name; (void)val; return true;
             }
             static ut32 my_reg_size(void *user, const char *name) { (void)user; (void)name; return 64; }

             /* Simple memory callbacks using a flat buffer */
             static ut8 my_mem[0x10000];
             static bool my_mem_read(void *user, ut64 addr, ut8 *buf, int len) {
                 memcpy (buf, my_mem + addr, len); return true;
             }
             static bool my_mem_write(void *user, ut64 addr, const ut8 *buf, int len) {
                 memcpy (my_mem + addr, buf, len); return true;
             }

             int main(void) {
                 REsilRegInterface reg_if = { .reg = NULL, .is_reg = my_is_reg, .reg_read = my_reg_read, .reg_write = my_reg_write, .reg_size = my_reg_size };
                 REsilMemInterface mem_if = { .mem = NULL, .mem_read = my_mem_read, .mem_write = my_mem_write };

                 REsil *esil = r_esil_new_ex (128, false, 64, &reg_if, &mem_if);
                 if (!esil) return -1;

                 // Evaluate an expression that reads RAX, adds 8 and leaves the result on the stack
                 r_esil_parse (esil, "rax,8,+");

                 // Pop the result as a string (caller frees it)
                 char *res = r_esil_pop (esil);
                 printf ("esil result: %s0, res);
                 free (res);

                 r_esil_free (esil);
                 return 0;
             }

       Low-level example: push/pop and expression-level debugging similar to the esil debugger (show stack,  run
       a single operation):

             REsil *esil = r_esil_new (32, 0, 64);
             // push two numbers, run the '+' op and inspect the result
             r_esil_pushnum (esil, 2);
             r_esil_pushnum (esil, 3);
             // run the '+' word directly (same as parsing "2,3,+")
             r_esil_runword (esil, "+");
             char *sum = r_esil_pop (esil);
             printf ("2 + 3 = %s0, sum);
             free (sum);

             // dump stack state (useful when interactively debugging expressions)
             r_esil_dumpstack (esil);

             r_esil_free (esil);

SEE ALSO

       r_anal(3), r_reg(3), r_io(3)

Debian                                         September 20, 2025                                      R_ESIL(3)