Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
R_SYSCALL(3)		     Library Functions Manual		    R_SYSCALL(3)

NAME
     r_syscall -- radare2 syscall information library

SYNOPSIS
     #include <r_syscall.h>

DESCRIPTION
     The  r_syscall  API  provides  a  lightweight,  architecture-  and OS-aware
     syscall database used by radare2 components such as the  assembler,  disas-
     sembler  and  analyzer.  It  exposes  utilities  to  load platform specific
     syscall tables, query syscall names and numbers,  parse  syscall  item  de-
     scriptions and access related system registers and I/O port mappings.

     The  primary object is RSyscall, which holds loaded SDB databases and small
     lookup helpers. The API is designed for fast in-process lookups and shallow
     ownership rules: callers allocate and free the context  with  the	provided
     constructors and share references with r_syscall_ref(RSyscall *sc).

INITIALIZATION
     Create  and  destroy syscall contexts using the following helpers. The con-
     structor returns a new, zero-initialized context with internal SDB contain-
     ers ready to be loaded by r_syscall_setup(RSyscall *s,  const  char  *arch,
     int bits, const char *cpu, const char *os).

     RSyscall * r_syscall_new(void)

     Allocates	and returns a new RSyscall instance. New instances have internal
     SDB fields allocated and default platform values set (but no  syscall  data
     loaded until r_syscall_setup(RSyscall *s, const char *arch, int bits, const
     char *cpu, const char *os, is, called).)

     void r_syscall_free(RSyscall *ctx)

     Decrements  the reference counter and frees the context when no more refer-
     ences   remain.   The   API   uses   simple   reference	counting;    use
     r_syscall_ref(RSyscall  *sc,  to,	create, an, additional, reference, when,
     sharing, the, object, between, subsystems, (for, example, binding, the, an-
     alyzer, and, assembler, to, the, same, syscall, database).)

SETUP
     Loading the correct syscall and sysregs tables for the target  platform  is
     done  with  bool  r_syscall_setup(RSyscall  *s, const char *arch, int bits,
     const char *cpu, const char *os)

     Call this after creating the context (or when the target architecture /  OS
     changes).	The function chooses the appropriate SDB file (or embedded gperf
     table)   using   the   pattern   "syscall/<os>-<arch>-<bits>"   and   "sys-
     regs/<arch>-<bits>-<cpu>".

     Typical  usage:  the  assembler/disassembler  initializes its local syscall
     context and calls r_syscall_setup(RSyscall *s, const char *arch, int  bits,
     const  char  *cpu,  const	char *os, with, the, same, parameters, used, to,
     configure, the, engine., Example, from, `libr/main/rasm2.c`:)

	   as->a->syscall = r_syscall_new();
	   r_syscall_setup (as->a->syscall, arch, bits, as->opt.cpu, as->opt.kernel);

     Note: the function normalizes common  aliases  (for  example  `android`  ->
     `linux`)  and  may switch internal defaults for certain architectures (e.g.
     x86 syscall port tables).

LOOKUP BY NUMBER AND NAME
     The main operations allow mapping from numbers to names  (and  more  struc-
     tured items), and from names to numbers. These helpers are the most used by
     analysis and assembly codepaths.

     RSyscallItem * r_syscall_get(RSyscall *ctx, int num, int swi)

     Given  a  syscall number and an optional software interrupt selector (swi),
     returns a newly allocated RSyscallItem describing the syscall  (name,  num-
     ber,  swi	and argument information). The caller owns the returned item and
     must free it with r_syscall_item_free(RSyscallItem *si).

     Example (used in `libr/core/canal.c` to label discovered SWI instructions):

	   int sig = r_syscall_get_num (core->anal->syscall, sysnumstr);
	   RSyscallItem *si = r_syscall_get (core->anal->syscall, snv, -1);
	   if (si) {
	       // annotate flags or print name
	       r_flag_set_next (core->flags, r_strf ("syscall.%s", si->name), cur, 1);
	       r_syscall_item_free (si);
	   } else {
	       r_flag_set_next (core->flags, r_strf ("syscall.%d", snv), cur, 1);
	   }

     int r_syscall_get_num(RSyscall *ctx, const char *str)

     Look up the numerical identifier for a syscall by name. This returns -1  on
     errors  or when the database is not loaded. Commonly used when an assembler
     or scripting helper needs to convert textual syscall names into numbers  to
     emit proper immediates.

     Example: get the syscall number for `write`:

	   int write_num = r_syscall_get_num (sc, "write");

     const char * r_syscall_get_i(RSyscall *ctx, int num, int swi)

     Returns the raw string key for a syscall entry (often the dotted key stored
     in  the  SDB). This helper is useful when you only need the textual mapping
     without allocating a full RSyscallItem.

LISTING
     RList * r_syscall_list(RSyscall *ctx)

     Enumerate the syscalls currently available for  the  loaded  configuration.
     The  function  returns a newly allocated RList of RSyscallItem objects; the
     caller is responsible for the list and item  deallocation.  Use  this  when
     building  UIs  or dump utilities that need a complete picture of the avail-
     able syscall set.

	   RList *list = r_syscall_list (sc);
	   // iterate and free using r_list_foreach or r_list_pop

SYSREGS AND I/O PORTS
     Some platforms provide named system registers (sysregs) and well-known  I/O
     port names. These helpers query the loaded sysregs DB or fall back to small
     built-in tables.

     const char * r_syscall_sysreg(RSyscall *s, const char *type, ut64 num)

     Return  a	string	describing a system register or resource of a given type
     (for example `io`, `sr` or vendor-specific namespaces) indexed by num.  The
     string  points  into  the SDB internal storage and must not be freed by the
     caller.

     const char * r_syscall_get_io(RSyscall *s, int ioport)

     Convenience wrapper to get an I/O port name by number. Internally it  tries
     `r_syscall_sysreg	(s,  "io",  ioport)` first and then consults a small in-
     memory table for common ports (for example on x86).

SYSITEM CREATION AND LIFETIME
     RSyscallItem * r_syscall_item_new_from_string(const char *name, const  char
     *s)

     Parse  a  compact	SDB-style syscall description string and return an allo-
     cated RSyscallItem. The  format  is  typically  a	comma  separated  string
     describing  the  swi, number, argument count and argument descriptors. This
     helper is used internally by the lookup functions and is exposed for  tools
     that need to construct items from raw SDB values.

     void r_syscall_item_free(RSyscallItem *si)

     Free an item previously returned by the API.

SOFTWARE INTERRUPTS (SWI)
     Some  architectures  multiplex syscall tables through different SWI numbers
     or selectors. The API exposes a small helper to retrieve  the  current  de-
     fault SWI for the loaded database.

     int r_syscall_get_swi(RSyscall *s)

     Returns  the default software interrupt number used by the currently loaded
     syscall table, or -1 on error.

     Typical callers pass `-1` for the `swi` parameter of r_syscall_get(RSyscall
     *ctx, int num, int swi), which causes the implementation to substitute  the
     configured  default  value  (see  the  internal `getswi` helper used by the
     library).

EXAMPLES
     This section  contains  practical	code  snippets	extracted  from  radare2
     sources showing common usage patterns.

     1) Binding and sharing a syscall context between analyzer and assembler:

	   // when initializing core subsystems
	   core->rasm->syscall = r_syscall_ref (core->anal->syscall); // share reference

	   // when creating an independent assembler context (rasm2 example)
	   as->a->syscall = r_syscall_new();
	   r_syscall_setup (as->a->syscall, arch, bits, as->opt.cpu, as->opt.kernel);

     2)  Annotating  discovered  SWI instructions in the analysis pipeline (from
     `libr/core/canal.c`):

	   int snv = (arch == R2_ARCH_THUMB)? op.val: (int)r_reg_getv (core->anal->reg, sn);
	   if (snv > 0 && snv < 0xFFFF) {
	       RSyscallItem *si = r_syscall_get (core->anal->syscall, snv, -1);
	       if (si) {
		   r_flag_set_next (core->flags, r_strf ("syscall.%s", si->name), cur, 1);
		   r_syscall_item_free (si);
	       } else {
		   r_flag_set_next (core->flags, r_strf ("syscall.%d", snv), cur, 1);
	       }
	   }

     3) Looking up a numeric value from a textual name for assembly and  script-
     ing helpers:

	   int num = r_syscall_get_num (sc, "write");
	   if (num >= 0) {
	       // emit syscall immediate or use it in analysis
	   }

     4) Enumerating and printing all loaded syscalls:

	   RList *list = r_syscall_list (sc);
	   RListIter *it;
	   RSyscallItem *si;
	   r_list_foreach (list, it, si) {
	       printf ("%s: swi=%d num=%d args=%d0, si->name, si->swi, si->num, si->args);
	   }
	   r_list_free (list);

SEE ALSO
     r_anal(3), r_esil(3)

FreeBSD ports 15.quarterly     September 20, 2025		    R_SYSCALL(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=r_syscall&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help