XRef
Documentation menu
xrefcode.com / docs / cli / slice

$ xref slice

On this page
  1. Usage
  2. Arguments and options
  3. Examples
  4. To fn_160bb0
  5. To fn_160bb0 --fields
  6. To fn_124d50
  7. To fn_fb8e0
  8. Reading the output
  9. Limits
  10. Provenance

Backward program slice: minimal pseudo-C statements and branches reaching a target address or text.

Usage

xref slice [OPTIONS] <ADDR>

Arguments and options

Arguments

<ADDR>
Function address or symbol name.

Options

--to <TO>
Target hex address, call name, field offset, or string substring inside the function.
--to-field <FIELD>
Target memory field: offset relative to a base register at an instruction address (+0x10 of rax@0xVA).
--fields
Rewrite raw pointer offsets as inferred ->f_<off> field hints before slicing.
--goto
Keep residual labels and gotos in the sliced pseudo-C.

Examples

All examples were recorded on public binaries; see Provenance.

To fn_160bb0

Command
$ xref -b xref.stripped slice 0xc7d60 --to fn_160bb0
Output
/* slice of 0xc7d60..0xc7fbf -> fn_160bb0 (37/131 lines) */
void fn_c7d60(void *arg_0, const void *arg_1, usize arg_2) {
  u8 slot_28; /* [rsp+0x28], addr-taken */
  usize slot_30; /* [rsp+0x30] */
  unk64 slot_40; /* [rsp+0x40], addr-taken */
  if (arg_2 == 0) {
    return; /* callers ignore rax */
  }
  const void *ptr_1 = arg_1;
  const void *v_2 = arg_1 + arg_2 * 24;
  void *v_4 = &slot_40;
  do {
    const u8 *ptr_6 = *(u64 *)(ptr_1 + 8);
    usize v_7 = *(u64 *)(ptr_1 + 16);
    /* fn_160550: source core/src/str/pattern.rs:1398; calls fn_1606e0, fn_160a43, fn_1605f8 */
    fn_160550(v_4, ptr_6, v_7, "goto L_", 7);
    /* fn_124d50: source core/src/str/pattern.rs:1131; calls fn_124e3a, fn_160bb0, fn_124e29 */
    fn_124d50(&slot_28, v_4);
    if (slot_28 != 0) {
      usize v_8 = slot_30;
      usize v_9 = (v_8 + 7);
      if (v_9 != 0) {
        if (v_9 < v_7) {
          if ((i8)((u8 *)ptr_6)[v_9] < -64) {
            /* fn_160bb0: noreturn; source core/src/str/mod.rs:486; calls fn_160bc0 */
            fn_160bb0(ptr_6, v_7, v_9, v_7, "src/loops.rs:45:36");
          }
        } else {
          if (v_9 != v_7) {
            /* fn_160bb0: noreturn; source core/src/str/mod.rs:486; calls fn_160bc0 */
            fn_160bb0(ptr_6, v_7, v_9, v_7, "src/loops.rs:45:36");
          }
        }
      }
    }
    ptr_1 = (ptr_1 + 24);
  } while (ptr_1 != v_2);
}
stderr
xref: load 509.5µs, total 4.6ms

To fn_160bb0 --fields

Command
$ xref -b xref.stripped slice 0xc7d60 --to fn_160bb0 --fields
Output
/* slice of 0xc7d60..0xc7fbf -> fn_160bb0 (37/132 lines) */
void fn_c7d60(void *arg_0, const void *arg_1, usize arg_2) {
  u8 slot_28; /* [rsp+0x28], addr-taken */
  usize slot_30; /* [rsp+0x30] */
  unk64 slot_40; /* [rsp+0x40], addr-taken */
  if (arg_2 == 0) {
    return; /* callers ignore rax */
  }
  const void *ptr_1 = arg_1;
  const void *v_2 = arg_1 + arg_2 * 24;
  void *v_4 = &slot_40;
  do {
    const u8 *ptr_6 = *(u64 *)(ptr_1 + 8);
    usize v_7 = *(u64 *)(ptr_1 + 16);
    /* fn_160550: source core/src/str/pattern.rs:1398; calls fn_1606e0, fn_160a43, fn_1605f8 */
    fn_160550(v_4, ptr_6, v_7, "goto L_", 7);
    /* fn_124d50: source core/src/str/pattern.rs:1131; calls fn_124e3a, fn_160bb0, fn_124e29 */
    fn_124d50(&slot_28, v_4);
    if (slot_28 != 0) {
      usize v_8 = slot_30;
      usize v_9 = (v_8 + 7);
      if (v_9 != 0) {
        if (v_9 < v_7) {
          if ((i8)((u8 *)ptr_6)[v_9] < -64) {
            /* fn_160bb0: noreturn; source core/src/str/mod.rs:486; calls fn_160bc0 */
            fn_160bb0(ptr_6, v_7, v_9, v_7, "src/loops.rs:45:36");
          }
        } else {
          if (v_9 != v_7) {
            /* fn_160bb0: noreturn; source core/src/str/mod.rs:486; calls fn_160bc0 */
            fn_160bb0(ptr_6, v_7, v_9, v_7, "src/loops.rs:45:36");
          }
        }
      }
    }
    ptr_1 = (ptr_1 + 24);
  } while (ptr_1 != v_2);
}
stderr
xref: load 625.2µs, total 4.7ms

To fn_124d50

Command
$ xref -b xref.stripped slice 0xc7d60 --to fn_124d50
Output
/* slice of 0xc7d60..0xc7fbf -> fn_124d50 (20/131 lines) */
void fn_c7d60(void *arg_0, const void *arg_1, usize arg_2) {
  u8 slot_28; /* [rsp+0x28], addr-taken */
  usize slot_30; /* [rsp+0x30] */
  unk64 slot_40; /* [rsp+0x40], addr-taken */
  if (arg_2 == 0) {
    return; /* callers ignore rax */
  }
  const void *ptr_1 = arg_1;
  const void *v_2 = arg_1 + arg_2 * 24;
  void *v_4 = &slot_40;
  do {
    const u8 *ptr_6 = *(u64 *)(ptr_1 + 8);
    usize v_7 = *(u64 *)(ptr_1 + 16);
    /* fn_160550: source core/src/str/pattern.rs:1398; calls fn_1606e0, fn_160a43, fn_1605f8 */
    fn_160550(v_4, ptr_6, v_7, "goto L_", 7);
    /* fn_124d50: source core/src/str/pattern.rs:1131; calls fn_124e3a, fn_160bb0, fn_124e29 */
    fn_124d50(&slot_28, v_4);
    ptr_1 = (ptr_1 + 24);
  } while (ptr_1 != v_2);
}
stderr
xref: load 606.8µs, total 4.5ms

To fn_fb8e0

Command
$ xref -b xref.stripped slice 0x9a8a0 --to fn_fb8e0
Output
/* slice of 0x9a8a0..0x9a97a -> fn_fb8e0 (23/64 lines) */
u8 fn_9a8a0(const void *arg_0, unk64 arg_1, unk64 arg_2) {
  usize v_1 = arg_1; /* rsi */
  const u8 *ptr_9; /* rax */
  unk64 slot_0; /* [rsp+0x0], addr-taken */
  unk64 slot_8; /* [rsp+0x8] */
  if (v_1 == 0) {
    ptr_9 = 0;
    return ptr_9;
  }
  if (((u64 *)*(u64 *)(arg_0))[v_1] != 1) {
    ptr_9 = 0;
    return ptr_9;
  }
  const void *ptr_3 = *(u64 *)(arg_0 + 24);
  unk64 v_4 = *(u64 *)(*(u64 *)(arg_0 + 16));
  if (v_1 == v_4 + 2) {
    usize v_5 = (v_4 + 1);
    unk64 v_8 = ((v_5 * 96) + *(u64 *)(ptr_3 + 8));
    slot_0 = 1;
    /* fn_fb8e0: calls fn_fb9c6, fn_fb920 */
    ptr_9 = fn_fb8e0(v_8, &slot_0);
  }
}
stderr
xref: load 613.6µs, total 3.0ms

Reading the output

Limits

Provenance

Recorded with a development build of xref after 0.4.0 on Linux x86-64, on xref.stripped = a stripped xref build (the binary of the home-page examples). Output is unchanged except that whitespace at the end of each line and empty lines at the end of the output are removed; long outputs are cut where marked.

Source: docs/cli/slice.md · generated for the site; edit the Markdown, not this page.