Rizin
unix-like reverse engineering framework and cli tools
rz-diff.c File Reference
#include <rz_core.h>
#include <rz_io.h>
#include <rz_bin.h>
#include <rz_diff.h>
#include <rz_util.h>
#include <rz_main.h>

Go to the source code of this file.

Classes

struct  diff_screen_t
 
struct  diff_context_t
 
struct  diff_io_t
 
struct  diff_file_t
 
struct  diff_function_t
 
struct  diff_colors_t
 
struct  diff_hex_view_t
 

Macros

#define MEGABYTE(x)   (x << 20)
 
#define SAFE_STR_DEF(x, y)   (x ? x : y)
 
#define SAFE_STR(x)   (x ? x : "")
 
#define IF_STRCMP_S(ret, x, y)
 
#define rz_diff_error(f, ...)    RZ_LOG_ERROR("rz-diff: error, " f, ##__VA_ARGS__)
 
#define rz_diff_error_ret(fail, f, ...)
 
#define rz_diff_error_opt(x, o, f, ...)
 
#define rz_diff_ctx_set(x, k, v)   (x)->k = (v)
 
#define rz_diff_set_def(x, d, v)
 
#define rz_diff_ctx_set_def(x, k, d, v)
 
#define rz_diff_ctx_set_val(x, k, d, v)
 
#define rz_diff_ctx_set_unsigned(x, k, i)
 
#define rz_diff_ctx_add_evar(x, o)
 
#define rz_diff_ctx_set_dist(x, t)   rz_diff_ctx_set_def(x, distance, DIFF_DISTANCE_UNKNOWN, t)
 
#define rz_diff_ctx_set_type(x, t)   rz_diff_ctx_set_def(x, type, DIFF_TYPE_UNKNOWN, t)
 
#define rz_diff_ctx_set_mode(x, m)   rz_diff_ctx_set_def(x, mode, DIFF_MODE_STANDARD, m)
 
#define rz_diff_ctx_set_opt(x, o)   rz_diff_ctx_set_def(x, option, DIFF_OPT_UNKNOWN, o)
 
#define rz_diff_file_get(df, n)   ((df)->file->o->n)
 
#define P(x)   (IS_PRINTABLE(x) ? x : '.')
 
#define printline(fmt, ...)   snprintf(line + lp, RZ_MAX(lsize - lp, 0), fmt, ##__VA_ARGS__)
 
#define printline(fmt, ...)   snprintf(line + lp, RZ_MAX(lsize - lp, 0), fmt, ##__VA_ARGS__)
 

Typedefs

typedef struct diff_screen_t DiffScreen
 
typedef struct diff_context_t DiffContext
 
typedef struct diff_io_t DiffIO
 
typedef struct diff_file_t DiffFile
 
typedef struct diff_function_t DiffFunction
 
typedef struct diff_colors_t DiffColors
 
typedef struct diff_hex_view_t DiffHexView
 
typedef enum diff_hex_len_t DiffHexLen
 

Enumerations

enum  DiffMode { DIFF_MODE_STANDARD = 0 , DIFF_MODE_JSON , DIFF_MODE_QUIET }
 
enum  DiffDistance { DIFF_DISTANCE_UNKNOWN = 0 , DIFF_DISTANCE_MYERS , DIFF_DISTANCE_LEVENSHTEIN }
 
enum  DiffType {
  DIFF_TYPE_UNKNOWN = 0 , DIFF_TYPE_BYTES , DIFF_TYPE_CLASSES , DIFF_TYPE_COMMAND ,
  DIFF_TYPE_ENTRIES , DIFF_TYPE_FIELDS , DIFF_TYPE_FUNCTIONS , DIFF_TYPE_IMPORTS ,
  DIFF_TYPE_LIBRARIES , DIFF_TYPE_LINES , DIFF_TYPE_SECTIONS , DIFF_TYPE_STRINGS ,
  DIFF_TYPE_SYMBOLS , DIFF_TYPE_PLOTDIFF
}
 
enum  DiffOption {
  DIFF_OPT_UNKNOWN = 0 , DIFF_OPT_ERROR , DIFF_OPT_HELP , DIFF_OPT_USAGE ,
  DIFF_OPT_VERSION , DIFF_OPT_DISTANCE , DIFF_OPT_UNIFIED , DIFF_OPT_GRAPH ,
  DIFF_OPT_HEX_VISUAL
}
 
enum  diff_hex_len_t { DIFF_HEX_8 = 58 , DIFF_HEX_16 = 90 , DIFF_HEX_32 = 154 }
 

Functions

static void rz_diff_show_help (bool usage_only)
 
static bool rz_diff_is_file (const char *file)
 
static void rz_diff_parse_arguments (int argc, const char **argv, DiffContext *ctx)
 
static void rz_diff_get_colors (DiffColors *dcolors, RzConsContext *ctx, bool colors)
 
static DiffIOrz_diff_io_open (const char *file)
 
static void rz_diff_io_close (DiffIO *dio)
 
static ut8rz_diff_slurp_file (const char *file, size_t *size)
 
static bool rz_diff_calculate_distance (DiffContext *ctx)
 
static RzBinFilecore_get_file (RzCoreFile *cfile)
 
static RzCoreFilerz_diff_load_file_with_core (const char *filename, const char *architecture, ut32 arch_bits, RzList *evars, bool colors)
 
static bool rz_diff_file_open (DiffFile *dfile, const char *filename)
 
static void rz_diff_file_close (DiffFile *file)
 
static const void * rz_diff_list_elem_at (const RzList *array, ut32 index)
 
static ut32 import_hash (const RzBinImport *elem)
 
static void import_stringify (const RzBinImport *elem, RzStrBuf *sb)
 
static int import_compare (const RzBinImport *a, const RzBinImport *b)
 
static RzDiffrz_diff_imports_new (DiffFile *dfile_a, DiffFile *dfile_b)
 
static ut32 symbol_hash_addr (const RzBinSymbol *elem)
 
static int symbol_compare_addr (const RzBinSymbol *a, const RzBinSymbol *b)
 
static void symbol_stringify_addr (const RzBinSymbol *elem, RzStrBuf *sb)
 
static ut32 symbol_hash (const RzBinSymbol *elem)
 
static int symbol_compare (const RzBinSymbol *a, const RzBinSymbol *b)
 
static void symbol_stringify (const RzBinSymbol *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_symbols_new (DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
 
static ut32 string_hash_addr (const RzBinString *elem)
 
static int string_compare_addr (const RzBinString *a, const RzBinString *b)
 
static void string_stringify_addr (const RzBinString *elem, RzStrBuf *sb)
 
static ut32 string_hash (const RzBinString *elem)
 
static int string_compare (const RzBinString *a, const RzBinString *b)
 
static void string_stringify (const RzBinString *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_strings_new (DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
 
static ut32 class_hash_addr (const RzBinClass *elem)
 
static int class_compare_addr (const RzBinClass *a, const RzBinClass *b)
 
static void class_stringify_addr (const RzBinClass *elem, RzStrBuf *sb)
 
static ut32 class_hash (const RzBinClass *elem)
 
static int class_compare (const RzBinClass *a, const RzBinClass *b)
 
static void class_stringify (const RzBinClass *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_classes_new (DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
 
static ut32 entry_hash (const RzBinAddr *elem)
 
static int entry_compare (const RzBinAddr *a, const RzBinAddr *b)
 
static void entry_stringify (const RzBinAddr *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_entries_new (DiffFile *dfile_a, DiffFile *dfile_b)
 
static ut32 libs_hash (const char *elem)
 
static int libs_compare (const char *a, const char *b)
 
static void libs_stringify (const char *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_libraries_new (DiffFile *dfile_a, DiffFile *dfile_b)
 
static ut32 section_hash_addr (const RzBinSection *elem)
 
static int section_compare_addr (const RzBinSection *a, const RzBinSection *b)
 
static void section_stringify_addr (const RzBinSection *elem, RzStrBuf *sb)
 
static ut32 section_hash (const RzBinSection *elem)
 
static int section_compare (const RzBinSection *a, const RzBinSection *b)
 
static void section_stringify (const RzBinSection *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_sections_new (DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
 
static ut32 field_hash_addr (const RzBinField *elem)
 
static int field_compare_addr (const RzBinField *a, const RzBinField *b)
 
static void field_stringify_addr (const RzBinField *elem, RzStrBuf *sb)
 
static ut32 field_hash (const RzBinField *elem)
 
static int field_compare (const RzBinField *a, const RzBinField *b)
 
static void field_stringify (const RzBinField *elem, RzStrBuf *sb)
 
static RzDiffrz_diff_fields_new (DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
 
static char * execute_command (const char *command, const char *filename, DiffContext *ctx)
 
static RzDiffrz_diff_command_new (DiffContext *ctx)
 
static bool rz_diff_unified_files (DiffContext *ctx)
 
static bool convert_offset_from_input (RzCore *core, const char *input, ut64 *offset)
 
static bool rz_diff_graphs_files (DiffContext *ctx)
 
static int diff_hexdump_partial (DiffHexView *hview, int hexlen, int lp, int lsize, const ut8 *bytes_a, const ut8 *bytes_b, ut64 address_a, ut64 address_b, ut64 size_a, ut64 size_b, ut64 pos, ssize_t read_a, ssize_t read_b, ssize_t skip_a, ssize_t skip_b)
 
static void diff_hexdump_line (DiffHexView *hview, DiffHexLen hlen, ut64 pos, ssize_t read_a, ssize_t read_b, ssize_t skip_a, ssize_t skip_b)
 
static int len_draw_hexdump (DiffHexView *hview)
 
static int seek_min_shift (DiffHexView *hview)
 
static int seek_min_value (DiffHexView *hview)
 
static int offset_len (DiffHexView *hview)
 
static bool rz_diff_draw_tui (DiffHexView *hview, bool show_help)
 
static char * visual_prompt (DiffHexView *hview, const char *prompt)
 
static void prompt_offset_and_seek (DiffHexView *hview, ut64 minseek)
 
static void prompt_offset_and_seek_file (DiffHexView *hview, ut64 minseek, bool is_file0)
 
static void find_next_diff (DiffHexView *hview, ut64 seek)
 
static void find_prev_diff (DiffHexView *hview, ut64 seek)
 
static void rz_diff_resize_buffer (DiffHexView *hview)
 
static bool rz_diff_hex_visual (DiffContext *ctx)
 
RZ_API int rz_main_rz_diff (int argc, const char **argv)
 

Macro Definition Documentation

◆ IF_STRCMP_S

#define IF_STRCMP_S (   ret,
  x,
 
)
Value:
do { \
if ((x) != (y) && (!(x) || !(y))) { \
return !(y) ? 1 : -1; \
} else if ((x) && (y) && (ret = strcmp((x), (y)))) { \
return ret; \
} \
} while (0)
int x
Definition: mipsasm.c:20

Definition at line 14 of file rz-diff.c.

◆ MEGABYTE

#define MEGABYTE (   x)    (x << 20)

Definition at line 11 of file rz-diff.c.

◆ P

#define P (   x)    (IS_PRINTABLE(x) ? x : '.')

◆ printline [1/2]

#define printline (   fmt,
  ... 
)    snprintf(line + lp, RZ_MAX(lsize - lp, 0), fmt, ##__VA_ARGS__)

◆ printline [2/2]

#define printline (   fmt,
  ... 
)    snprintf(line + lp, RZ_MAX(lsize - lp, 0), fmt, ##__VA_ARGS__)

◆ rz_diff_ctx_add_evar

#define rz_diff_ctx_add_evar (   x,
 
)
Value:
do { \
char *copy = rz_str_new(o); \
if (!copy || !rz_list_append((x)->evars, copy)) { \
free(copy); \
rz_diff_error_opt(x, DIFF_OPT_ERROR, "cannot add evar '%s' to list\n", o); \
} \
} while (0)
@ DIFF_OPT_ERROR
Definition: rz-diff.c:54
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865

Definition at line 181 of file rz-diff.c.

◆ rz_diff_ctx_set

#define rz_diff_ctx_set (   x,
  k,
  v 
)    (x)->k = (v)

Definition at line 146 of file rz-diff.c.

◆ rz_diff_ctx_set_def

#define rz_diff_ctx_set_def (   x,
  k,
  d,
  v 
)
Value:
do { \
if ((x)->k != (d)) { \
rz_diff_error_opt(x, DIFF_OPT_UNKNOWN, "invalid combination of arguments for '-%c' (expected " #d " but found something else)\n", c); \
} \
(x)->k = (v); \
} while (0)
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
@ DIFF_OPT_UNKNOWN
Definition: rz-diff.c:53
#define d(i)
Definition: sha256.c:44
#define c(i)
Definition: sha256.c:43

Definition at line 157 of file rz-diff.c.

◆ rz_diff_ctx_set_dist

#define rz_diff_ctx_set_dist (   x,
 
)    rz_diff_ctx_set_def(x, distance, DIFF_DISTANCE_UNKNOWN, t)

Definition at line 190 of file rz-diff.c.

◆ rz_diff_ctx_set_mode

#define rz_diff_ctx_set_mode (   x,
 
)    rz_diff_ctx_set_def(x, mode, DIFF_MODE_STANDARD, m)

Definition at line 192 of file rz-diff.c.

◆ rz_diff_ctx_set_opt

#define rz_diff_ctx_set_opt (   x,
 
)    rz_diff_ctx_set_def(x, option, DIFF_OPT_UNKNOWN, o)

Definition at line 193 of file rz-diff.c.

◆ rz_diff_ctx_set_type

#define rz_diff_ctx_set_type (   x,
 
)    rz_diff_ctx_set_def(x, type, DIFF_TYPE_UNKNOWN, t)

Definition at line 191 of file rz-diff.c.

◆ rz_diff_ctx_set_unsigned

#define rz_diff_ctx_set_unsigned (   x,
  k,
  i 
)
Value:
do { \
(x)->k = strtoull((i), NULL, 0); \
if ((x)->k < 1) { \
rz_diff_error_opt(x, DIFF_OPT_UNKNOWN, "argument must be > 0\n"); \
} \
} while (0)
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27

Definition at line 173 of file rz-diff.c.

◆ rz_diff_ctx_set_val

#define rz_diff_ctx_set_val (   x,
  k,
  d,
  v 
)
Value:
do { \
if ((x)->k != (d)) { \
rz_diff_error_opt(x, DIFF_OPT_UNKNOWN, "invalid combination of arguments for '-%c' (expected " #d " but found something else)\n", c); \
} \
(x)->k = (v); \
} while (0)

Definition at line 165 of file rz-diff.c.

◆ rz_diff_error

#define rz_diff_error (   f,
  ... 
)     RZ_LOG_ERROR("rz-diff: error, " f, ##__VA_ARGS__)

Definition at line 134 of file rz-diff.c.

◆ rz_diff_error_opt

#define rz_diff_error_opt (   x,
  o,
  f,
  ... 
)
Value:
(x)->option = o; \
RZ_LOG_ERROR("rz-diff: error, " f, ##__VA_ARGS__); \
return
#define f(i)
Definition: sha256.c:46
Definition: getopt.h:84

Definition at line 141 of file rz-diff.c.

◆ rz_diff_error_ret

#define rz_diff_error_ret (   fail,
  f,
  ... 
)
Value:
RZ_LOG_ERROR("rz-diff: error, " f, ##__VA_ARGS__); \
return (fail)
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define fail(test)
Definition: tests.h:29

Definition at line 137 of file rz-diff.c.

◆ rz_diff_file_get

#define rz_diff_file_get (   df,
  n 
)    ((df)->file->o->n)

Definition at line 668 of file rz-diff.c.

◆ rz_diff_set_def

#define rz_diff_set_def (   x,
  d,
  v 
)
Value:
do { \
if ((x) != (d)) { \
RZ_LOG_ERROR("rz-diff: error, invalid combination of arguments for '-%c' (expected " #d " but found something else)\n", c); \
return; \
} \
(x) = (v); \
} while (0)

Definition at line 148 of file rz-diff.c.

◆ SAFE_STR

#define SAFE_STR (   x)    (x ? x : "")

Definition at line 13 of file rz-diff.c.

◆ SAFE_STR_DEF

#define SAFE_STR_DEF (   x,
 
)    (x ? x : y)

Definition at line 12 of file rz-diff.c.

Typedef Documentation

◆ DiffColors

typedef struct diff_colors_t DiffColors

◆ DiffContext

typedef struct diff_context_t DiffContext

◆ DiffFile

typedef struct diff_file_t DiffFile

◆ DiffFunction

typedef struct diff_function_t DiffFunction

◆ DiffHexLen

typedef enum diff_hex_len_t DiffHexLen

◆ DiffHexView

typedef struct diff_hex_view_t DiffHexView

◆ DiffIO

typedef struct diff_io_t DiffIO

◆ DiffScreen

typedef struct diff_screen_t DiffScreen

Enumeration Type Documentation

◆ diff_hex_len_t

Enumerator
DIFF_HEX_8 
DIFF_HEX_16 
DIFF_HEX_32 

Definition at line 1494 of file rz-diff.c.

1494  {
1495  DIFF_HEX_8 = 58,
1496  DIFF_HEX_16 = 90,
1497  DIFF_HEX_32 = 154,
1498 } DiffHexLen;
enum diff_hex_len_t DiffHexLen
@ DIFF_HEX_8
Definition: rz-diff.c:1495
@ DIFF_HEX_16
Definition: rz-diff.c:1496
@ DIFF_HEX_32
Definition: rz-diff.c:1497

◆ DiffDistance

Enumerator
DIFF_DISTANCE_UNKNOWN 
DIFF_DISTANCE_MYERS 
DIFF_DISTANCE_LEVENSHTEIN 

Definition at line 29 of file rz-diff.c.

29  {
33 } DiffDistance;
DiffDistance
Definition: rz-diff.c:29
@ DIFF_DISTANCE_MYERS
Definition: rz-diff.c:31
@ DIFF_DISTANCE_UNKNOWN
Definition: rz-diff.c:30
@ DIFF_DISTANCE_LEVENSHTEIN
Definition: rz-diff.c:32

◆ DiffMode

enum DiffMode
Enumerator
DIFF_MODE_STANDARD 
DIFF_MODE_JSON 
DIFF_MODE_QUIET 

Definition at line 23 of file rz-diff.c.

23  {
27 } DiffMode;
DiffMode
Definition: rz-diff.c:23
@ DIFF_MODE_QUIET
Definition: rz-diff.c:26
@ DIFF_MODE_STANDARD
Definition: rz-diff.c:24
@ DIFF_MODE_JSON
Definition: rz-diff.c:25

◆ DiffOption

enum DiffOption
Enumerator
DIFF_OPT_UNKNOWN 
DIFF_OPT_ERROR 
DIFF_OPT_HELP 
DIFF_OPT_USAGE 
DIFF_OPT_VERSION 
DIFF_OPT_DISTANCE 
DIFF_OPT_UNIFIED 
DIFF_OPT_GRAPH 
DIFF_OPT_HEX_VISUAL 

Definition at line 52 of file rz-diff.c.

52  {
53  DIFF_OPT_UNKNOWN = 0,
62 } DiffOption;
DiffOption
Definition: rz-diff.c:52
@ DIFF_OPT_HELP
Definition: rz-diff.c:55
@ DIFF_OPT_DISTANCE
Definition: rz-diff.c:58
@ DIFF_OPT_GRAPH
Definition: rz-diff.c:60
@ DIFF_OPT_UNIFIED
Definition: rz-diff.c:59
@ DIFF_OPT_VERSION
Definition: rz-diff.c:57
@ DIFF_OPT_HEX_VISUAL
Definition: rz-diff.c:61
@ DIFF_OPT_USAGE
Definition: rz-diff.c:56

◆ DiffType

enum DiffType
Enumerator
DIFF_TYPE_UNKNOWN 
DIFF_TYPE_BYTES 
DIFF_TYPE_CLASSES 
DIFF_TYPE_COMMAND 
DIFF_TYPE_ENTRIES 
DIFF_TYPE_FIELDS 
DIFF_TYPE_FUNCTIONS 
DIFF_TYPE_IMPORTS 
DIFF_TYPE_LIBRARIES 
DIFF_TYPE_LINES 
DIFF_TYPE_SECTIONS 
DIFF_TYPE_STRINGS 
DIFF_TYPE_SYMBOLS 
DIFF_TYPE_PLOTDIFF 

Definition at line 35 of file rz-diff.c.

35  {
50 } DiffType;
DiffType
Definition: rz-diff.c:35
@ DIFF_TYPE_LINES
Definition: rz-diff.c:45
@ DIFF_TYPE_LIBRARIES
Definition: rz-diff.c:44
@ DIFF_TYPE_FIELDS
Definition: rz-diff.c:41
@ DIFF_TYPE_BYTES
Definition: rz-diff.c:37
@ DIFF_TYPE_FUNCTIONS
Definition: rz-diff.c:42
@ DIFF_TYPE_SECTIONS
Definition: rz-diff.c:46
@ DIFF_TYPE_IMPORTS
Definition: rz-diff.c:43
@ DIFF_TYPE_ENTRIES
Definition: rz-diff.c:40
@ DIFF_TYPE_STRINGS
Definition: rz-diff.c:47
@ DIFF_TYPE_PLOTDIFF
Definition: rz-diff.c:49
@ DIFF_TYPE_COMMAND
Definition: rz-diff.c:39
@ DIFF_TYPE_SYMBOLS
Definition: rz-diff.c:48
@ DIFF_TYPE_CLASSES
Definition: rz-diff.c:38
@ DIFF_TYPE_UNKNOWN
Definition: rz-diff.c:36

Function Documentation

◆ class_compare()

static int class_compare ( const RzBinClass a,
const RzBinClass b 
)
static

Definition at line 901 of file rz-diff.c.

901  {
902  int ret;
903  IF_STRCMP_S(ret, a->super, b->super);
904  IF_STRCMP_S(ret, a->name, b->name);
905  return 0;
906 }
#define IF_STRCMP_S(ret, x, y)
Definition: rz-diff.c:14
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41

References a, b, and IF_STRCMP_S.

Referenced by rz_diff_classes_new().

◆ class_compare_addr()

static int class_compare_addr ( const RzBinClass a,
const RzBinClass b 
)
static

Definition at line 884 of file rz-diff.c.

884  {
885  int ret;
886  IF_STRCMP_S(ret, a->super, b->super);
887  IF_STRCMP_S(ret, a->name, b->name);
888  return a->addr - b->addr;
889 }

References a, b, and IF_STRCMP_S.

Referenced by rz_diff_classes_new().

◆ class_hash()

static ut32 class_hash ( const RzBinClass elem)
static

Definition at line 895 of file rz-diff.c.

895  {
896  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
897  hash ^= rz_diff_hash_data((const ut8 *)elem->super, strlen(elem->super));
898  return hash;
899 }
uint32_t ut32
RZ_API ut32 rz_diff_hash_data(RZ_NULLABLE const ut8 *buffer, ut32 size)
Calculates the hash of any given data.
Definition: diff.c:103
uint8_t ut8
Definition: lh5801.h:11
char * super
Definition: rz_bin.h:649
char * name
Definition: rz_bin.h:647

References rz_bin_class_t::name, rz_diff_hash_data(), and rz_bin_class_t::super.

Referenced by rz_diff_classes_new().

◆ class_hash_addr()

static ut32 class_hash_addr ( const RzBinClass elem)
static

Definition at line 876 of file rz-diff.c.

876  {
877  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
878  hash ^= rz_diff_hash_data((const ut8 *)elem->super, strlen(elem->super));
879  hash ^= (ut32)(elem->addr >> 32);
880  hash ^= (ut32)elem->addr;
881  return hash;
882 }

References rz_bin_class_t::addr, rz_bin_class_t::name, rz_diff_hash_data(), and rz_bin_class_t::super.

Referenced by rz_diff_classes_new().

◆ class_stringify()

static void class_stringify ( const RzBinClass elem,
RzStrBuf sb 
)
static

Definition at line 908 of file rz-diff.c.

908  {
909  rz_strbuf_setf(sb, "%s %s\n", SAFE_STR(elem->super), elem->name);
910 }
static SblHeader sb
Definition: bin_mbn.c:26
#define SAFE_STR(x)
Definition: rz-diff.c:13
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2

References rz_bin_class_t::name, rz_strbuf_setf(), SAFE_STR, sb, and rz_bin_class_t::super.

Referenced by rz_diff_classes_new().

◆ class_stringify_addr()

static void class_stringify_addr ( const RzBinClass elem,
RzStrBuf sb 
)
static

Definition at line 891 of file rz-diff.c.

891  {
892  rz_strbuf_setf(sb, "0x%016" PFMT64x " %s %s\n", elem->addr, SAFE_STR(elem->super), elem->name);
893 }
#define PFMT64x
Definition: rz_types.h:393

References rz_bin_class_t::addr, rz_bin_class_t::name, PFMT64x, rz_strbuf_setf(), SAFE_STR, sb, and rz_bin_class_t::super.

Referenced by rz_diff_classes_new().

◆ convert_offset_from_input()

static bool convert_offset_from_input ( RzCore core,
const char *  input,
ut64 offset 
)
static

Definition at line 1398 of file rz-diff.c.

1398  {
1401  return true;
1402  }
1403 
1404  RzFlagItem *fi = rz_flag_get(core->flags, input);
1405  if (fi) {
1406  *offset = fi->offset;
1407  return true;
1408  }
1409 
1410  return false;
1411 }
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
Definition: flag.c:310
voidpf uLong offset
Definition: ioapi.h:144
RZ_API int rz_num_is_valid_input(RzNum *num, const char *input_value)
Definition: unum.c:676
RZ_API ut64 rz_num_get_input_value(RzNum *num, const char *input_value)
Definition: unum.c:681
RzFlag * flags
Definition: rz_core.h:330
ut64 offset
Definition: rz_flag.h:38
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)

References rz_core_t::flags, input(), NULL, rz_flag_item_t::offset, rz_flag_get(), rz_num_get_input_value(), and rz_num_is_valid_input().

Referenced by rz_diff_graphs_files().

◆ core_get_file()

static RzBinFile* core_get_file ( RzCoreFile cfile)
inlinestatic

Definition at line 550 of file rz-diff.c.

550  {
551  return rz_pvector_at(&cfile->binfiles, 0);
552 }
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236

References benchmark::cfile, and rz_pvector_at().

Referenced by rz_diff_load_file_with_core().

◆ diff_hexdump_line()

static void diff_hexdump_line ( DiffHexView hview,
DiffHexLen  hlen,
ut64  pos,
ssize_t  read_a,
ssize_t  read_b,
ssize_t  skip_a,
ssize_t  skip_b 
)
inlinestatic

Definition at line 1560 of file rz-diff.c.

1560  {
1561  int width = hview->screen.width;
1562  int height = hview->screen.height;
1563  char *line = hview->line;
1564  const ut8 *buffer_a = hview->buffer_a;
1565  const ut8 *buffer_b = hview->buffer_b;
1566  ut64 address_a = hview->address_a;
1567  ut64 address_b = hview->address_b;
1568  int lp = 0;
1569  int lsize = width * height;
1570  int hexlen = 0;
1571 
1572  switch (hlen) {
1573  case DIFF_HEX_16:
1574  hexlen = 16;
1575  break;
1576  case DIFF_HEX_32:
1577  hexlen = 32;
1578  break;
1579  default:
1580  hexlen = 8;
1581  break;
1582  }
1583 
1584 #define printline(fmt, ...) snprintf(line + lp, RZ_MAX(lsize - lp, 0), fmt, ##__VA_ARGS__)
1585  lp = diff_hexdump_partial(hview, hexlen, 0, lsize, buffer_a, buffer_b, address_a, address_b, hview->size_a, hview->size_b, pos, read_a, read_b, skip_a, skip_b);
1586  lp += printline(" | ");
1587  lp = diff_hexdump_partial(hview, hexlen, lp, lsize, buffer_b, buffer_a, address_b, address_a, hview->size_b, hview->size_a, pos, read_b, read_a, skip_b, skip_a);
1588  lp += printline(" |");
1589 #undef printline
1590 }
static int diff_hexdump_partial(DiffHexView *hview, int hexlen, int lp, int lsize, const ut8 *bytes_a, const ut8 *bytes_b, ut64 address_a, ut64 address_b, ut64 size_a, ut64 size_b, ut64 pos, ssize_t read_a, ssize_t read_b, ssize_t skip_a, ssize_t skip_b)
Definition: rz-diff.c:1500
#define printline(fmt,...)
line
Definition: setup.py:34
DiffScreen screen
Definition: rz-diff.c:131
char * line
Definition: rz-diff.c:119
ut8 * buffer_b
Definition: rz-diff.c:121
ut64 address_b
Definition: rz-diff.c:125
ut64 address_a
Definition: rz-diff.c:124
ut8 * buffer_a
Definition: rz-diff.c:120
int height
Definition: rz-diff.c:66
int pos
Definition: main.c:11
int width
Definition: main.c:10
int height
Definition: main.c:10
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, diff_hex_view_t::buffer_a, diff_hex_view_t::buffer_b, DIFF_HEX_16, DIFF_HEX_32, diff_hexdump_partial(), diff_screen_t::height, height, diff_hex_view_t::line, setup::line, pos, printline, diff_hex_view_t::screen, diff_hex_view_t::size_a, diff_hex_view_t::size_b, ut64(), diff_screen_t::width, and width.

Referenced by rz_diff_draw_tui().

◆ diff_hexdump_partial()

static int diff_hexdump_partial ( DiffHexView hview,
int  hexlen,
int  lp,
int  lsize,
const ut8 bytes_a,
const ut8 bytes_b,
ut64  address_a,
ut64  address_b,
ut64  size_a,
ut64  size_b,
ut64  pos,
ssize_t  read_a,
ssize_t  read_b,
ssize_t  skip_a,
ssize_t  skip_b 
)
inlinestatic

Definition at line 1500 of file rz-diff.c.

1500  {
1501  const char *number = hview->colors.number;
1502  const char *match = hview->colors.match;
1503  const char *unmatch = hview->colors.unmatch;
1504  const char *reset = hview->colors.reset;
1505  ssize_t i;
1506  char *line = hview->line;
1507 
1508 #define P(x) (IS_PRINTABLE(x) ? x : '.')
1509 #define printline(fmt, ...) snprintf(line + lp, RZ_MAX(lsize - lp, 0), fmt, ##__VA_ARGS__)
1510  // write to buffer fileA offset + hex bytes
1511  lp += printline("%s0x%016" PFMT64x "%s | ", number, address_a + pos, reset);
1512  for (i = 0; i < hexlen && i < read_a; ++i) {
1513  if (pos + i >= size_a || pos + i < skip_a) {
1514  // if the byte is outside the range [0 - fileA size) then do not write any hex
1515  memset(line + lp, ' ', 3);
1516  lp += 3;
1517  } else if (i < read_b && pos + i >= skip_b) {
1518  // if the byte is inside the range [0 - fileA size) check bytes_b for match/mismatch
1519  const char *color = bytes_a[pos + i] == bytes_b[pos + i] ? match : unmatch;
1520  lp += printline("%s%02x%s ", color, bytes_a[pos + i], reset);
1521  } else {
1522  // if the byte is inside the range [0 - fileA size) but address_b
1523  // is outside [0 - fileB size) then is a mismatch
1524  lp += printline("%s%02x%s ", unmatch, bytes_a[pos + i], reset);
1525  }
1526  }
1527  if (i < hexlen) {
1528  // fill any missing space to have fileA bytes aligned
1529  memset(line + lp, ' ', (hexlen - i) * 3);
1530  lp += (hexlen - i) * 3;
1531  }
1532 
1533  // print now printable chars of the printed hex values
1534  lp += printline(" | ");
1535  for (i = 0; i < hexlen && i < read_a; ++i) {
1536  if (pos + i >= size_a || pos + i < skip_a) {
1537  // if the byte is outside the range [0 - fileA size) then do not write any hex
1538  line[lp] = ' ';
1539  lp++;
1540  } else if (i < read_b && pos + i >= skip_b) {
1541  // if the byte is inside the range [0 - fileA size) check bytes_b for match/mismatch
1542  const char *color = bytes_a[pos + i] == bytes_b[pos + i] ? match : unmatch;
1543  lp += printline("%s%c%s", color, P(bytes_a[pos + i]), reset);
1544  } else {
1545  // if the byte is inside the range [0 - fileA size) but address_b
1546  // is outside [0 - fileB size) then is a mismatch
1547  lp += printline("%s%c%s", unmatch, P(bytes_a[pos + i]), reset);
1548  }
1549  }
1550  if (i < hexlen) {
1551  // fill any missing space to have fileA bytes aligned
1552  memset(line + lp, ' ', (hexlen - i));
1553  lp += (hexlen - i);
1554  }
1555  return lp;
1556 #undef printline
1557 #undef P
1558 }
unsigned char match[65280+2]
Definition: gun.c:165
return memset(p, 0, total)
#define P(x)
int ssize_t
Definition: sftypes.h:39
const char * reset
Definition: rz-diff.c:115
const char * number
Definition: rz-diff.c:111
const char * match
Definition: rz-diff.c:112
const char * unmatch
Definition: rz-diff.c:113
DiffColors colors
Definition: rz-diff.c:129
Definition: engine.c:71
static int color
Definition: visual.c:20

References color, diff_hex_view_t::colors, i, diff_hex_view_t::line, setup::line, diff_colors_t::match, match, memset(), diff_colors_t::number, P, PFMT64x, pos, printline, diff_colors_t::reset, and diff_colors_t::unmatch.

Referenced by diff_hexdump_line().

◆ entry_compare()

static int entry_compare ( const RzBinAddr a,
const RzBinAddr b 
)
static

Definition at line 952 of file rz-diff.c.

952  {
953  st64 ret;
954  ret = ((st64)b->paddr) - ((st64)a->paddr);
955  if (ret) {
956  return ret;
957  }
958  ret = ((st64)b->vaddr) - ((st64)a->vaddr);
959  if (ret) {
960  return ret;
961  }
962  return b->type - a->type;
963 }
#define st64
Definition: rz_types_base.h:10

References a, b, and st64.

Referenced by rz_diff_entries_new().

◆ entry_hash()

static ut32 entry_hash ( const RzBinAddr elem)
static

Definition at line 942 of file rz-diff.c.

942  {
943  ut32 hash = rz_diff_hash_data((const ut8 *)"entry", strlen("entry"));
944  hash ^= (ut32)(elem->vaddr >> 32);
945  hash ^= (ut32)elem->vaddr;
946  hash ^= (ut32)(elem->paddr >> 32);
947  hash ^= (ut32)elem->paddr;
948  hash ^= (ut32)elem->type;
949  return hash;
950 }
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187

References rz_bin_addr_t::paddr, rz_diff_hash_data(), rz_bin_addr_t::type, and rz_bin_addr_t::vaddr.

Referenced by rz_diff_entries_new().

◆ entry_stringify()

static void entry_stringify ( const RzBinAddr elem,
RzStrBuf sb 
)
static

Definition at line 965 of file rz-diff.c.

965  {
966  const char *name = NULL;
967  switch (elem->type) {
969  name = "program";
970  break;
972  name = "main";
973  break;
975  name = "init";
976  break;
978  name = "fini";
979  break;
981  name = "tls";
982  break;
984  name = "preinit";
985  break;
986  default:
987  name = "unknown";
988  break;
989  }
990  rz_strbuf_setf(sb, "virt: 0x%016" PFMT64x " phys: 0x%016" PFMT64x " entry %s\n", elem->vaddr, elem->paddr, name);
991 }
#define RZ_BIN_ENTRY_TYPE_PREINIT
Definition: rz_bin.h:38
#define RZ_BIN_ENTRY_TYPE_TLS
Definition: rz_bin.h:37
#define RZ_BIN_ENTRY_TYPE_FINI
Definition: rz_bin.h:36
#define RZ_BIN_ENTRY_TYPE_INIT
Definition: rz_bin.h:35
#define RZ_BIN_ENTRY_TYPE_PROGRAM
Definition: rz_bin.h:33
#define RZ_BIN_ENTRY_TYPE_MAIN
Definition: rz_bin.h:34
Definition: z80asm.h:102

References NULL, rz_bin_addr_t::paddr, PFMT64x, RZ_BIN_ENTRY_TYPE_FINI, RZ_BIN_ENTRY_TYPE_INIT, RZ_BIN_ENTRY_TYPE_MAIN, RZ_BIN_ENTRY_TYPE_PREINIT, RZ_BIN_ENTRY_TYPE_PROGRAM, RZ_BIN_ENTRY_TYPE_TLS, rz_strbuf_setf(), sb, rz_bin_addr_t::type, and rz_bin_addr_t::vaddr.

Referenced by rz_diff_entries_new().

◆ execute_command()

static char* execute_command ( const char *  command,
const char *  filename,
DiffContext ctx 
)
static

Definition at line 1259 of file rz-diff.c.

1259  {
1260  RzCoreFile *cfile = rz_diff_load_file_with_core(filename, ctx->architecture, ctx->arch_bits, ctx->evars, ctx->colors);
1261  if (!cfile) {
1262  return NULL;
1263  }
1264 
1265  if (ctx->analyze_all && !rz_core_analysis_everything(cfile->core, false, NULL)) {
1266  rz_diff_error("cannot analyze binary '%s'\n", ctx->file_a);
1267  }
1268 
1269  char *output = rz_core_cmd_str(cfile->core, command);
1270  rz_core_free(cfile->core);
1271  return output;
1272 }
RZ_API bool rz_core_analysis_everything(RzCore *core, bool experimental, char *dh_orig)
Definition: canalysis.c:5784
RZ_API char * rz_core_cmd_str(RzCore *core, const char *cmd)
Executes a rizin command and returns the stdout as a string.
Definition: cmd.c:5513
const char * filename
Definition: ioapi.h:137
RZ_API void rz_core_free(RzCore *c)
Definition: core.c:2683
static RzCoreFile * rz_diff_load_file_with_core(const char *filename, const char *architecture, ut32 arch_bits, RzList *evars, bool colors)
Definition: rz-diff.c:554
#define rz_diff_error(f,...)
Definition: rz-diff.c:134
const char * command
Definition: main.c:7
diff_output_t output
Definition: zipcmp.c:237

References benchmark::cfile, command, NULL, output, rz_core_analysis_everything(), rz_core_cmd_str(), rz_core_free(), rz_diff_error, and rz_diff_load_file_with_core().

Referenced by rz_diff_command_new().

◆ field_compare()

static int field_compare ( const RzBinField a,
const RzBinField b 
)
static

Definition at line 1218 of file rz-diff.c.

1218  {
1219  int ret;
1220  IF_STRCMP_S(ret, a->name, b->name);
1221  IF_STRCMP_S(ret, a->type, b->type);
1222  return 0;
1223 }

References a, b, and IF_STRCMP_S.

Referenced by rz_diff_fields_new().

◆ field_compare_addr()

static int field_compare_addr ( const RzBinField a,
const RzBinField b 
)
static

Definition at line 1192 of file rz-diff.c.

1192  {
1193  st64 ret;
1194  IF_STRCMP_S(ret, a->name, b->name);
1195  IF_STRCMP_S(ret, a->type, b->type);
1196  ret = ((st64)b->size) - ((st64)a->size);
1197  if (ret) {
1198  return ret;
1199  }
1200  ret = ((st64)b->paddr) - ((st64)a->paddr);
1201  if (ret) {
1202  return ret;
1203  }
1204  return ((st64)b->vaddr) - ((st64)a->vaddr);
1205 }

References a, b, IF_STRCMP_S, and st64.

Referenced by rz_diff_fields_new().

◆ field_hash()

static ut32 field_hash ( const RzBinField elem)
static

Definition at line 1212 of file rz-diff.c.

1212  {
1213  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
1214  hash ^= rz_diff_hash_data((const ut8 *)elem->type, strlen(SAFE_STR(elem->type)));
1215  return hash;
1216 }
char * name
Definition: rz_bin.h:767
char * type
Definition: rz_bin.h:768

References rz_bin_field_t::name, rz_diff_hash_data(), SAFE_STR, and rz_bin_field_t::type.

Referenced by rz_diff_fields_new().

◆ field_hash_addr()

static ut32 field_hash_addr ( const RzBinField elem)
static

Definition at line 1182 of file rz-diff.c.

1182  {
1183  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
1184  hash ^= rz_diff_hash_data((const ut8 *)elem->type, strlen(SAFE_STR(elem->type)));
1185  hash ^= (ut32)(elem->paddr >> 32);
1186  hash ^= (ut32)elem->paddr;
1187  hash ^= (ut32)(elem->vaddr >> 32);
1188  hash ^= (ut32)elem->vaddr;
1189  return hash;
1190 }
ut64 vaddr
Definition: rz_bin.h:762
ut64 paddr
Definition: rz_bin.h:763

References rz_bin_field_t::name, rz_bin_field_t::paddr, rz_diff_hash_data(), SAFE_STR, rz_bin_field_t::type, and rz_bin_field_t::vaddr.

Referenced by rz_diff_fields_new().

◆ field_stringify()

static void field_stringify ( const RzBinField elem,
RzStrBuf sb 
)
static

Definition at line 1225 of file rz-diff.c.

1225  {
1226  rz_strbuf_setf(sb, "%s %s\n", SAFE_STR(elem->type), elem->name);
1227 }

References rz_bin_field_t::name, rz_strbuf_setf(), SAFE_STR, sb, and rz_bin_field_t::type.

Referenced by rz_diff_fields_new().

◆ field_stringify_addr()

static void field_stringify_addr ( const RzBinField elem,
RzStrBuf sb 
)
static

Definition at line 1207 of file rz-diff.c.

1207  {
1208  rz_strbuf_setf(sb, "virt: 0x%016" PFMT64x " phys: 0x%016" PFMT64x " %-8s %s\n",
1209  elem->vaddr, elem->paddr, SAFE_STR(elem->type), elem->name);
1210 }

References rz_bin_field_t::name, rz_bin_field_t::paddr, PFMT64x, rz_strbuf_setf(), SAFE_STR, sb, rz_bin_field_t::type, and rz_bin_field_t::vaddr.

Referenced by rz_diff_fields_new().

◆ find_next_diff()

static void find_next_diff ( DiffHexView hview,
ut64  seek 
)
static

Definition at line 1909 of file rz-diff.c.

1909  {
1910  if (!hview->buffer_a || !hview->buffer_b) {
1911  return;
1912  }
1913 
1914  DiffIO *io_a = hview->io_a;
1915  DiffIO *io_b = hview->io_b;
1916  ssize_t read_a = 0, read_b = 0;
1917  ssize_t minread = 0, minseek = 0;
1918  ut64 address_a = hview->address_a + seek;
1919  ut64 address_b = hview->address_b + seek;
1920  ut64 minsize = RZ_MIN(hview->size_a, hview->size_b);
1921  if (RZ_MIN(io_a->filesize, io_b->filesize) < seek) {
1922  hview->address_a = 0;
1923  hview->address_b = 0;
1924  return;
1925  }
1926  do {
1927  read_a = rz_io_pread_at(io_a->io, address_a, hview->buffer_a, minsize);
1928  read_b = rz_io_pread_at(io_b->io, address_b, hview->buffer_b, minsize);
1929  if (read_a < 1 || read_b < 1) {
1930  break;
1931  }
1932  minread = RZ_MIN(read_a, read_b);
1933  if (minread != minsize && !memcmp(hview->buffer_a, hview->buffer_b, minread)) {
1934  address_a += RZ_MAX(minread - seek, 0);
1935  address_b += RZ_MAX(minread - seek, 0);
1936  break;
1937  } else if (minread == minsize && !memcmp(hview->buffer_a, hview->buffer_b, minsize)) {
1938  address_a += minsize;
1939  address_b += minsize;
1940  continue;
1941  }
1942  minread = RZ_MIN(minsize, minread);
1943  minseek = RZ_MIN(seek, minread);
1944  for (ssize_t i = 0; i < minread; i += minseek) {
1945  if (memcmp(&hview->buffer_a[i], &hview->buffer_b[i], minseek)) {
1946  hview->address_a = address_a;
1947  hview->address_b = address_b;
1948  return;
1949  }
1950  address_a += minseek;
1951  address_b += minseek;
1952  }
1953  } while (1);
1954 
1955  if (address_a >= io_a->filesize) {
1956  address_a = io_a->filesize - seek;
1957  }
1958 
1959  if (address_b >= io_b->filesize) {
1960  address_b = io_b->filesize - seek;
1961  }
1962 
1963  hview->address_a = address_a;
1964  hview->address_b = address_b;
1965 }
RZ_API int rz_io_pread_at(RzIO *io, ut64 paddr, ut8 *buf, int len)
Definition: io.c:269
#define RZ_MIN(x, y)
#define RZ_MAX(x, y)
DiffIO * io_a
Definition: rz-diff.c:126
DiffIO * io_b
Definition: rz-diff.c:127
RzIO * io
Definition: rz-diff.c:91
ut64 filesize
Definition: rz-diff.c:90
static int seek(char *argv[])

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, diff_hex_view_t::buffer_a, diff_hex_view_t::buffer_b, diff_io_t::filesize, i, diff_io_t::io, diff_hex_view_t::io_a, diff_hex_view_t::io_b, rz_io_pread_at(), RZ_MAX, RZ_MIN, seek(), diff_hex_view_t::size_a, diff_hex_view_t::size_b, and ut64().

Referenced by rz_diff_hex_visual().

◆ find_prev_diff()

static void find_prev_diff ( DiffHexView hview,
ut64  seek 
)
static

Definition at line 1967 of file rz-diff.c.

1967  {
1968  if (!hview->buffer_a || !hview->buffer_b) {
1969  return;
1970  }
1971 
1972  DiffIO *io_a = hview->io_a;
1973  DiffIO *io_b = hview->io_b;
1974  ssize_t read_a = 0, read_b = 0;
1975  st64 address_a = hview->address_a;
1976  st64 address_b = hview->address_b;
1977 
1978  do {
1979  address_a -= seek;
1980  address_b -= seek;
1981  if (address_a < 0) {
1982  address_a = 0;
1983  }
1984  if (address_b < 0) {
1985  address_b = 0;
1986  }
1987  read_a = rz_io_pread_at(io_a->io, address_a, hview->buffer_a, seek);
1988  read_b = rz_io_pread_at(io_b->io, address_b, hview->buffer_b, seek);
1989  if (read_a < 1 || read_b < 1) {
1990  break;
1991  }
1992  if (memcmp(hview->buffer_a, hview->buffer_b, seek)) {
1993  break;
1994  }
1995  if (address_a == 0 || address_b == 0) {
1996  break;
1997  }
1998  } while (1);
1999  hview->address_a = RZ_MAX(address_a, 0);
2000  hview->address_b = RZ_MAX(address_b, 0);
2001 }

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, diff_hex_view_t::buffer_a, diff_hex_view_t::buffer_b, diff_io_t::io, diff_hex_view_t::io_a, diff_hex_view_t::io_b, rz_io_pread_at(), RZ_MAX, seek(), and st64.

Referenced by rz_diff_hex_visual().

◆ import_compare()

static int import_compare ( const RzBinImport a,
const RzBinImport b 
)
static

Definition at line 690 of file rz-diff.c.

690  {
691  int ret;
692  IF_STRCMP_S(ret, a->name, b->name);
693  IF_STRCMP_S(ret, a->bind, b->bind);
694  IF_STRCMP_S(ret, a->type, b->type);
695  return 0;
696 }

References a, b, and IF_STRCMP_S.

Referenced by rz_diff_imports_new().

◆ import_hash()

static ut32 import_hash ( const RzBinImport elem)
static

Definition at line 678 of file rz-diff.c.

678  {
679  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
680  hash ^= rz_diff_hash_data((const ut8 *)elem->bind, strlen(SAFE_STR(elem->bind)));
681  hash ^= rz_diff_hash_data((const ut8 *)elem->type, strlen(SAFE_STR(elem->type)));
682  return hash;
683 }
const char * type
Definition: rz_bin.h:704
const char * bind
Definition: rz_bin.h:703
char * name
Definition: rz_bin.h:701

References rz_bin_import_t::bind, rz_bin_import_t::name, rz_diff_hash_data(), SAFE_STR, and rz_bin_import_t::type.

Referenced by rz_diff_imports_new().

◆ import_stringify()

static void import_stringify ( const RzBinImport elem,
RzStrBuf sb 
)
static

Definition at line 685 of file rz-diff.c.

685  {
686  rz_strbuf_setf(sb, "%-7s %-7s %s\n", SAFE_STR_DEF(elem->bind, RZ_BIN_BIND_UNKNOWN_STR),
688 }
#define SAFE_STR_DEF(x, y)
Definition: rz-diff.c:12
#define RZ_BIN_TYPE_UNKNOWN_STR
Definition: rz_bin.h:134
#define RZ_BIN_BIND_UNKNOWN_STR
Definition: rz_bin.h:115

References rz_bin_import_t::bind, rz_bin_import_t::name, RZ_BIN_BIND_UNKNOWN_STR, RZ_BIN_TYPE_UNKNOWN_STR, rz_strbuf_setf(), SAFE_STR_DEF, sb, and rz_bin_import_t::type.

Referenced by rz_diff_imports_new().

◆ len_draw_hexdump()

static int len_draw_hexdump ( DiffHexView hview)
inlinestatic

Definition at line 1592 of file rz-diff.c.

1592  {
1593  int width = hview->screen.width;
1594  if (width >= (DIFF_HEX_32 * 2)) {
1595  return DIFF_HEX_32;
1596  } else if (width >= (DIFF_HEX_16 * 2)) {
1597  return DIFF_HEX_16;
1598  }
1599  return DIFF_HEX_8;
1600 }

References DIFF_HEX_16, DIFF_HEX_32, DIFF_HEX_8, diff_hex_view_t::screen, diff_screen_t::width, and width.

Referenced by rz_diff_draw_tui().

◆ libs_compare()

static int libs_compare ( const char *  a,
const char *  b 
)
static

Definition at line 1027 of file rz-diff.c.

1027  {
1028  int ret;
1029  IF_STRCMP_S(ret, a, b);
1030  return 0;
1031 }

References a, b, and IF_STRCMP_S.

Referenced by rz_diff_libraries_new().

◆ libs_hash()

static ut32 libs_hash ( const char *  elem)
static

Definition at line 1023 of file rz-diff.c.

1023  {
1024  return rz_diff_hash_data((const ut8 *)elem, strlen(elem));
1025 }

References rz_diff_hash_data().

Referenced by rz_diff_libraries_new().

◆ libs_stringify()

static void libs_stringify ( const char *  elem,
RzStrBuf sb 
)
static

Definition at line 1033 of file rz-diff.c.

1033  {
1034  rz_strbuf_setf(sb, "%s\n", SAFE_STR(elem));
1035 }

References rz_strbuf_setf(), SAFE_STR, and sb.

Referenced by rz_diff_libraries_new().

◆ offset_len()

static int offset_len ( DiffHexView hview)
inlinestatic

Definition at line 1622 of file rz-diff.c.

1622  {
1623  ut64 filesize = RZ_MAX(hview->io_a->filesize, hview->io_b->filesize);
1624  if (filesize > UT32_MAX) {
1625  return 16;
1626  } else if (filesize > UT16_MAX) {
1627  return 8;
1628  }
1629  return 4;
1630 }
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT16_MAX

References diff_io_t::filesize, diff_hex_view_t::io_a, diff_hex_view_t::io_b, RZ_MAX, UT16_MAX, UT32_MAX, and ut64().

Referenced by rz_diff_draw_tui().

◆ prompt_offset_and_seek()

static void prompt_offset_and_seek ( DiffHexView hview,
ut64  minseek 
)
static

Definition at line 1854 of file rz-diff.c.

1854  {
1855  char *value = visual_prompt(hview, " you can input an absolute offset or a relative offset by adding the prefix + or -\n offset");
1856  if (value) {
1857  const char *p = rz_str_trim_head_ro(value);
1858  if (!IS_DIGIT(*p) && *p != '-' && *p != '+') {
1859  free(value);
1860  return;
1861  }
1862  st64 number = strtoll((*p == '+' || *p == '-') ? p + 1 : p, NULL, 0);
1863  if (*p == '-') {
1864  hview->address_a -= number;
1865  hview->address_b -= number;
1866  } else if (*p == '+') {
1867  hview->address_a += number;
1868  hview->address_b += number;
1869  } else {
1870  hview->address_a = number;
1871  hview->address_b = number;
1872  }
1873  }
1874  free(value);
1875 }
static int value
Definition: cmd_api.c:93
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * p
Definition: libc.cpp:67
static char * visual_prompt(DiffHexView *hview, const char *prompt)
Definition: rz-diff.c:1840
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
#define IS_DIGIT(x)
Definition: rz_str_util.h:11

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, free(), IS_DIGIT, NULL, p, rz_str_trim_head_ro(), st64, value, and visual_prompt().

Referenced by rz_diff_hex_visual().

◆ prompt_offset_and_seek_file()

static void prompt_offset_and_seek_file ( DiffHexView hview,
ut64  minseek,
bool  is_file0 
)
static

Definition at line 1877 of file rz-diff.c.

1877  {
1878  char *value = visual_prompt(hview, " you can input an absolute offset or a relative offset by adding the prefix + or -\n offset");
1879  if (value) {
1880  const char *p = rz_str_trim_head_ro(value);
1881  if (!IS_DIGIT(*p) && *p != '-' && *p != '+') {
1882  free(value);
1883  return;
1884  }
1885  st64 number = strtoll((*p == '+' || *p == '-') ? p + 1 : p, NULL, 0);
1886  if (*p == '-') {
1887  if (is_file0) {
1888  hview->address_a -= number;
1889  } else {
1890  hview->address_b -= number;
1891  }
1892  } else if (*p == '+') {
1893  if (is_file0) {
1894  hview->address_a += number;
1895  } else {
1896  hview->address_b += number;
1897  }
1898  } else {
1899  if (is_file0) {
1900  hview->address_a = number;
1901  } else {
1902  hview->address_b = number;
1903  }
1904  }
1905  }
1906  free(value);
1907 }

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, free(), IS_DIGIT, NULL, p, rz_str_trim_head_ro(), st64, value, and visual_prompt().

Referenced by rz_diff_hex_visual().

◆ rz_diff_calculate_distance()

static bool rz_diff_calculate_distance ( DiffContext ctx)
static

Definition at line 486 of file rz-diff.c.

486  {
487  size_t a_size = 0;
488  size_t b_size = 0;
489  ut8 *a_buffer = NULL;
490  ut8 *b_buffer = NULL;
491  ut32 distance = 0;
492  double similarity = 0.0;
493 
494  if (!(a_buffer = rz_diff_slurp_file(ctx->file_a, &a_size))) {
495  goto rz_diff_calculate_distance_bad;
496  }
497 
498  if (!(b_buffer = rz_diff_slurp_file(ctx->file_b, &b_size))) {
499  goto rz_diff_calculate_distance_bad;
500  }
501 
502  switch (ctx->distance) {
503  case DIFF_DISTANCE_MYERS:
504  if (!rz_diff_myers_distance(a_buffer, a_size, b_buffer, b_size, &distance, &similarity)) {
505  rz_diff_error("failed to calculate distance with myers algorithm\n");
506  goto rz_diff_calculate_distance_bad;
507  }
508  break;
510  if (!rz_diff_levenstein_distance(a_buffer, a_size, b_buffer, b_size, &distance, &similarity)) {
511  rz_diff_error("failed to calculate distance with levenstein algorithm\n");
512  goto rz_diff_calculate_distance_bad;
513  }
514  break;
515  default:
516  rz_diff_error("unknown distance algorithm\n");
517  goto rz_diff_calculate_distance_bad;
518  }
519 
520  if (ctx->mode == DIFF_MODE_JSON) {
521  PJ *pj = pj_new();
522  if (!pj) {
523  rz_diff_error("failed to allocate json\n");
524  goto rz_diff_calculate_distance_bad;
525  }
526  pj_o(pj);
527  pj_kd(pj, "similarity", similarity);
528  pj_kn(pj, "distance", distance);
529  pj_end(pj);
530  printf("%s\n", pj_string(pj));
531  pj_free(pj);
532  } else if (ctx->mode == DIFF_MODE_QUIET) {
533  printf("%.3f\n", similarity);
534  printf("%d\n", distance);
535  } else {
536  // DIFF_MODE_STANDARD
537  printf("similarity: %.3f\n", similarity);
538  printf("distance: %d\n", distance);
539  }
540  free(a_buffer);
541  free(b_buffer);
542  return true;
543 
544 rz_diff_calculate_distance_bad:
545  free(a_buffer);
546  free(b_buffer);
547  return false;
548 }
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
RZ_API bool rz_diff_myers_distance(RZ_NONNULL const ut8 *a, ut32 la, RZ_NONNULL const ut8 *b, ut32 lb, RZ_NULLABLE ut32 *distance, RZ_NULLABLE double *similarity)
Calculates the distance between two buffers using the Myers algorithm.
Definition: distance.c:14
RZ_API bool rz_diff_levenstein_distance(RZ_NONNULL const ut8 *a, ut32 la, RZ_NONNULL const ut8 *b, ut32 lb, RZ_NULLABLE ut32 *distance, RZ_NULLABLE double *similarity)
Calculates the distance between two buffers using the Levenshtein algorithm.
Definition: distance.c:68
static ut8 * rz_diff_slurp_file(const char *file, size_t *size)
Definition: rz-diff.c:449
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_kd(PJ *j, const char *k, double d)
Definition: pj.c:136
Definition: rz_pj.h:12

References DIFF_DISTANCE_LEVENSHTEIN, DIFF_DISTANCE_MYERS, DIFF_MODE_JSON, DIFF_MODE_QUIET, free(), NULL, pj_end(), pj_free(), pj_kd(), pj_kn(), pj_new(), pj_o(), pj_string(), printf(), rz_diff_error, rz_diff_levenstein_distance(), rz_diff_myers_distance(), and rz_diff_slurp_file().

Referenced by rz_main_rz_diff().

◆ rz_diff_classes_new()

static RzDiff* rz_diff_classes_new ( DiffFile dfile_a,
DiffFile dfile_b,
bool  compare_addr 
)
static

Definition at line 912 of file rz-diff.c.

912  {
913  RzList *list_a = NULL;
914  RzList *list_b = NULL;
915 
916  list_a = rz_diff_file_get(dfile_a, classes);
917  if (!list_a) {
918  rz_diff_error_ret(NULL, "cannot get classes from '%s'\n", dfile_a->dio->filename);
919  }
920 
921  list_b = rz_diff_file_get(dfile_b, classes);
922  if (!list_b) {
923  rz_diff_error_ret(NULL, "cannot get classes from '%s'\n", dfile_b->dio->filename);
924  }
925 
928 
929  RzDiffMethods methods = {
931  .elem_hash = (RzDiffMethodElemHash)(compare_addr ? class_hash_addr : class_hash),
933  .stringify = (RzDiffMethodStringify)(compare_addr ? class_stringify_addr : class_stringify),
934  .ignore = NULL,
935  };
936 
937  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
938 }
static RzList * classes(RzBinFile *bf)
Definition: bin_dex.c:71
RZ_API RZ_OWN RzDiff * rz_diff_generic_new(RZ_BORROW const void *a, ut32 a_size, RZ_BORROW const void *b, ut32 b_size, RZ_NONNULL RzDiffMethods *methods)
Returns the structure needed to diff arrays of user defined types.
Definition: diff.c:259
static int compare(const char *s1, const char *s2, int l1, int l2)
Definition: chmd.c:864
static const void * rz_diff_list_elem_at(const RzList *array, ut32 index)
Definition: rz-diff.c:672
#define rz_diff_error_ret(fail, f,...)
Definition: rz-diff.c:137
static ut32 class_hash_addr(const RzBinClass *elem)
Definition: rz-diff.c:876
static int class_compare(const RzBinClass *a, const RzBinClass *b)
Definition: rz-diff.c:901
static void class_stringify(const RzBinClass *elem, RzStrBuf *sb)
Definition: rz-diff.c:908
static int class_compare_addr(const RzBinClass *a, const RzBinClass *b)
Definition: rz-diff.c:884
static ut32 class_hash(const RzBinClass *elem)
Definition: rz-diff.c:895
static void class_stringify_addr(const RzBinClass *elem, RzStrBuf *sb)
Definition: rz-diff.c:891
#define rz_diff_file_get(df, n)
Definition: rz-diff.c:668
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
const void *(* RzDiffMethodElemAt)(RZ_BORROW const void *array, ut32 index)
Definition: rz_diff.h:36
ut32(* RzDiffMethodElemHash)(RZ_BORROW const void *elem)
Definition: rz_diff.h:37
void(* RzDiffMethodStringify)(RZ_BORROW const void *elem, RZ_BORROW RzStrBuf *sb)
Definition: rz_diff.h:40
int(* RzDiffMethodCompare)(RZ_BORROW const void *a_elem, RZ_BORROW const void *b_elem)
Definition: rz_diff.h:38
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
DiffIO * dio
Definition: rz-diff.c:100
const char * filename
Definition: rz-diff.c:89
RzDiffMethodElemAt elem_at
can be either be an element of A or B
Definition: rz_diff.h:42

References class_compare(), class_compare_addr(), class_hash(), class_hash_addr(), class_stringify(), class_stringify_addr(), classes(), compare(), diff_file_t::dio, rz_diff_methods_t::elem_at, diff_io_t::filename, NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), and rz_list_sort().

Referenced by rz_diff_unified_files().

◆ rz_diff_command_new()

static RzDiff* rz_diff_command_new ( DiffContext ctx)
static

Definition at line 1274 of file rz-diff.c.

1274  {
1275  char *output_a = NULL;
1276  char *output_b = NULL;
1277 
1278  output_a = execute_command(ctx->input_a, ctx->file_a, ctx);
1279  if (!output_a) {
1280  rz_diff_error_ret(NULL, "cannot execute command '%s' on file '%s'\n", ctx->input_a, ctx->file_a);
1281  }
1282 
1283  output_b = execute_command(ctx->input_b, ctx->file_b, ctx);
1284  if (!output_b) {
1285  free(output_a);
1286  rz_diff_error_ret(NULL, "cannot execute command '%s' on file '%s'\n", ctx->input_b, ctx->file_b);
1287  }
1288 
1289  RzDiff *diff = rz_diff_lines_new(output_a, output_b, NULL);
1290  free(output_a);
1291  free(output_b);
1292  return diff;
1293 }
RZ_API RZ_OWN RzDiff * rz_diff_lines_new(RZ_BORROW const char *a, RZ_BORROW const char *b, RZ_NULLABLE RzDiffIgnoreLine ignore)
Returns the structure needed to diff lines.
Definition: diff.c:219
static char * execute_command(const char *command, const char *filename, DiffContext *ctx)
Definition: rz-diff.c:1259
Definition: diff.c:89

References execute_command(), free(), NULL, rz_diff_error_ret, and rz_diff_lines_new().

Referenced by rz_diff_unified_files().

◆ rz_diff_draw_tui()

static bool rz_diff_draw_tui ( DiffHexView hview,
bool  show_help 
)
static

Definition at line 1632 of file rz-diff.c.

1632  {
1633  ssize_t read_a = 0, read_b = 0;
1634  char *line = hview->line;
1635  int shift = 8, offlen = 16, xpos = 0;
1636  int width = hview->screen.width;
1637  int height = hview->screen.height;
1638  int lsize = width * height;
1639  DiffHexLen hlen = 0;
1640  DiffIO *io_a = hview->io_a;
1641  DiffIO *io_b = hview->io_b;
1642  ut64 filesize_a = hview->io_a->filesize;
1643  ut64 filesize_b = hview->io_b->filesize;
1644  ut64 max_rows = height - 2;
1645  ut64 skip_a = 0;
1646  ut64 skip_b = 0;
1647  RzConsCanvas *canvas = hview->canvas;
1648  const char *reset = hview->colors.reset;
1649  const char *legenda = hview->colors.legenda;
1650  const char *toolbar = NULL;
1651  bool utf8 = rz_cons_singleton()->use_utf8;
1652  const char *arrow_up = utf8 ? RUNE_ARROW_UP " " : "/\\";
1653  const char *arrow_down = utf8 ? RUNE_ARROW_DOWN " " : "\\/";
1654  const char *arrow_right = utf8 ? RUNE_ARROW_RIGHT " " : "> ";
1655  const char *arrow_left = utf8 ? RUNE_ARROW_LEFT " " : "< ";
1656 
1657  if (!line || !hview->buffer_a || !hview->buffer_b) {
1658  return false;
1659  }
1660 
1661  offlen = offset_len(hview);
1662  hlen = len_draw_hexdump(hview);
1663  xpos = RZ_MAX((width / 2) - hlen, 0);
1664 
1665  const char *p = NULL;
1666  const char *file_a = io_a->filename;
1667  const char *file_b = io_b->filename;
1668 
1669  p = io_a->filename;
1670  while ((p = strstr(file_a, RZ_SYS_DIR))) {
1671  file_a = p + 1;
1672  }
1673 
1674  p = io_b->filename;
1675  while ((p = strstr(file_b, RZ_SYS_DIR))) {
1676  file_b = p + 1;
1677  }
1678 
1679  if (hview->column_descr) {
1680  max_rows--;
1681  }
1682 
1683  if (hview->address_a > hview->size_a && (hview->address_a + hview->size_a) < hview->size_a) {
1684  // underflow
1685  ut64 size = hview->address_a + hview->size_a;
1686  ut64 offset_p = hview->size_a - size;
1687  read_a = rz_io_pread_at(io_a->io, 0, hview->buffer_a + offset_p, size);
1688  if (read_a > 0) {
1689  // include also excluded bytes from underflow
1690  read_a += offset_p;
1691  skip_a = offset_p;
1692  }
1693  } else {
1694  read_a = rz_io_pread_at(io_a->io, hview->address_a, hview->buffer_a, hview->size_a);
1695  }
1696 
1697  if (hview->address_b > hview->size_b && (hview->address_b + hview->size_b) < hview->size_b) {
1698  // underflow
1699  ut64 size = hview->address_b + hview->size_b;
1700  ut64 offset_p = hview->size_b - size;
1701  read_b = rz_io_pread_at(io_b->io, 0, hview->buffer_b + offset_p, size);
1702  if (read_b > 0) {
1703  // include also excluded bytes from underflow
1704  read_b += offset_p;
1705  skip_b = offset_p;
1706  }
1707  } else {
1708  read_b = rz_io_pread_at(io_b->io, hview->address_b, hview->buffer_b, hview->size_b);
1709  }
1710 
1712  rz_cons_clear();
1713  rz_cons_canvas_clear(canvas);
1714  shift = seek_min_shift(hview);
1715  for (ut64 h = 0, pos = 0; h < max_rows; ++h) {
1716  // draw hexadecimal values
1717  pos = h << shift;
1718  diff_hexdump_line(hview, hlen, pos, read_a - pos, read_b - pos, skip_a, skip_b);
1719  rz_cons_canvas_gotoxy(canvas, xpos, h + (hview->column_descr ? 2 : 1));
1720  rz_cons_canvas_write(canvas, line);
1721  }
1722 
1723  switch (len_draw_hexdump(hview)) {
1724  case DIFF_HEX_32: toolbar = " 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F"; break;
1725  case DIFF_HEX_16: toolbar = " 0 1 2 3 4 5 6 7 8 9 A B C D E F"; break;
1726  default: toolbar = " 0 1 2 3 4 5 6 7"; break;
1727  }
1728 
1729  rz_cons_canvas_box(canvas, 0, 0, width, height - 1, reset);
1730  if (hview->column_descr) {
1731  rz_cons_canvas_gotoxy(canvas, xpos + 21, 1);
1732  rz_cons_canvas_write(canvas, toolbar);
1733  rz_cons_canvas_gotoxy(canvas, xpos, 0);
1734  } else {
1735  rz_cons_canvas_gotoxy(canvas, xpos, 0);
1736  }
1737  snprintf(line, lsize, " [%*" PFMT64x "]( %.42s )", offlen, filesize_a, file_a);
1738  rz_cons_canvas_write(canvas, line);
1739 
1740  if (hview->column_descr) {
1741  rz_cons_canvas_gotoxy(canvas, xpos + hlen + 22, 1);
1742  rz_cons_canvas_write(canvas, toolbar);
1743  rz_cons_canvas_gotoxy(canvas, xpos + hlen, 0);
1744  } else {
1745  rz_cons_canvas_gotoxy(canvas, xpos + hlen, 0);
1746  }
1747  snprintf(line, lsize, " [%*" PFMT64x "]( %.42s )", offlen, filesize_b, file_b);
1748  rz_cons_canvas_write(canvas, line);
1749 
1750  // clang-format off
1751  toolbar = " "
1752  "%s1 2%s -/+0x%x | "
1753  "%sZ A%s file0 +/-1 | "
1754  "%sC D%s file1 +/-1 | "
1755  "%sG B%s end/begin | "
1756  "%sN M%s next/prev | "
1757  "%s%s%s%s +/-%u | "
1758  "%s%s%s%s +/-1 | "
1759  "%s:%s seek";
1760  snprintf(line, lsize, toolbar
1761  , legenda, reset, (1 << shift) * max_rows
1762  , legenda, reset
1763  , legenda, reset
1764  , legenda, reset
1765  , legenda, reset
1766  , legenda, arrow_down, arrow_up, reset, 1 << shift
1767  , legenda, arrow_left, arrow_right, reset
1768  , legenda, reset);
1769  // clang-format on
1770 
1771  rz_cons_canvas_gotoxy(canvas, 0, height);
1772  rz_cons_canvas_write(canvas, line);
1773 
1774  if (show_help) {
1775  rz_cons_canvas_fill(canvas, 4, 2, 56, 16, ' ');
1776  rz_cons_canvas_box(canvas, 4, 2, 56, 16, legenda);
1777 
1778  snprintf(line, lsize, "%sHelp page%s\n", legenda, reset);
1779  rz_cons_canvas_gotoxy(canvas, 6, 3);
1780  rz_cons_canvas_write(canvas, line);
1781 
1782  snprintf(line, lsize, "%s1 2%s increase/decrease the offsets by 0x%x\n", legenda, reset, (1 << shift) * (height - 2));
1783  rz_cons_canvas_gotoxy(canvas, 6, 5);
1784  rz_cons_canvas_write(canvas, line);
1785 
1786  snprintf(line, lsize, "%sZ A%s increase/decrease the offset of the file0 by 1\n", legenda, reset);
1787  rz_cons_canvas_gotoxy(canvas, 6, 6);
1788  rz_cons_canvas_write(canvas, line);
1789 
1790  snprintf(line, lsize, "%sC D%s increase/decrease the offset of the file1 by 1\n", legenda, reset);
1791  rz_cons_canvas_gotoxy(canvas, 6, 7);
1792  rz_cons_canvas_write(canvas, line);
1793 
1794  snprintf(line, lsize, "%sN M%s next/previous difference\n", legenda, reset);
1795  rz_cons_canvas_gotoxy(canvas, 6, 8);
1796  rz_cons_canvas_write(canvas, line);
1797 
1798  snprintf(line, lsize, "%sG B%s seek to end/begin\n", legenda, reset);
1799  rz_cons_canvas_gotoxy(canvas, 6, 9);
1800  rz_cons_canvas_write(canvas, line);
1801 
1802  snprintf(line, lsize, "%s9%s sets both offsets to a common value\n", legenda, reset);
1803  rz_cons_canvas_gotoxy(canvas, 6, 10);
1804  rz_cons_canvas_write(canvas, line);
1805 
1806  snprintf(line, lsize, "%s0%s shows/hides the column legenda\n", legenda, reset);
1807  rz_cons_canvas_gotoxy(canvas, 6, 11);
1808  rz_cons_canvas_write(canvas, line);
1809 
1810  snprintf(line, lsize, "%s%s %s%s increase/decrease both offsets by %u\n", legenda, arrow_down, arrow_up, reset, 1 << shift);
1811  rz_cons_canvas_gotoxy(canvas, 6, 12);
1812  rz_cons_canvas_write(canvas, line);
1813 
1814  snprintf(line, lsize, "%s%s %s%s increase/decrease both offsets by 1\n", legenda, arrow_left, arrow_right, reset);
1815  rz_cons_canvas_gotoxy(canvas, 6, 13);
1816  rz_cons_canvas_write(canvas, line);
1817 
1818  snprintf(line, lsize, "%s:%s seek at offset (relative via +-)\n", legenda, reset);
1819  rz_cons_canvas_gotoxy(canvas, 6, 14);
1820  rz_cons_canvas_write(canvas, line);
1821 
1822  snprintf(line, lsize, "%s3%s file0 seek at offset (relative via +-)\n", legenda, reset);
1823  rz_cons_canvas_gotoxy(canvas, 6, 15);
1824  rz_cons_canvas_write(canvas, line);
1825 
1826  snprintf(line, lsize, "%s4%s file1 seek at offset (relative via +-)\n", legenda, reset);
1827  rz_cons_canvas_gotoxy(canvas, 6, 16);
1828  rz_cons_canvas_write(canvas, line);
1829  }
1830 
1831  rz_cons_canvas_print(canvas);
1832  rz_cons_flush();
1833 
1834  // allow to refresh the terminal
1835  // before printing again the ui
1836  rz_sys_usleep(200);
1837  return true;
1838 }
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
RZ_API void rz_cons_canvas_print(RzConsCanvas *c)
Definition: canvas.c:423
RZ_API void rz_cons_canvas_write(RzConsCanvas *c, const char *s)
Definition: canvas.c:283
RZ_API bool rz_cons_canvas_gotoxy(RzConsCanvas *c, int x, int y)
Definition: canvas.c:184
RZ_API void rz_cons_canvas_fill(RzConsCanvas *c, int x, int y, int w, int h, char ch)
Definition: canvas.c:551
RZ_API void rz_cons_canvas_clear(RzConsCanvas *c)
Definition: canvas.c:174
RZ_API void rz_cons_canvas_box(RzConsCanvas *c, int x, int y, int w, int h, const char *color)
Definition: canvas.c:486
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
RZ_API void rz_cons_goto_origin_reset(void)
Definition: cons.c:732
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API void rz_cons_clear(void)
Definition: cons.c:787
voidpf void uLong size
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
static int len_draw_hexdump(DiffHexView *hview)
Definition: rz-diff.c:1592
static int seek_min_shift(DiffHexView *hview)
Definition: rz-diff.c:1602
static int offset_len(DiffHexView *hview)
Definition: rz-diff.c:1622
static void diff_hexdump_line(DiffHexView *hview, DiffHexLen hlen, ut64 pos, ssize_t read_a, ssize_t read_b, ssize_t skip_a, ssize_t skip_b)
Definition: rz-diff.c:1560
static int show_help(const char *argv0, int line)
Definition: rz-find.c:173
#define RUNE_ARROW_RIGHT
Definition: rz_cons.h:409
#define RUNE_ARROW_DOWN
Definition: rz_cons.h:412
#define RUNE_ARROW_UP
Definition: rz_cons.h:411
#define RUNE_ARROW_LEFT
Definition: rz_cons.h:410
RZ_API int rz_sys_usleep(int usecs)
Sleep for usecs microseconds.
Definition: sys.c:317
#define RZ_SYS_DIR
Definition: rz_types.h:218
#define h(i)
Definition: sha256.c:48
const char * legenda
Definition: rz-diff.c:114
RzConsCanvas * canvas
Definition: rz-diff.c:130
bool column_descr
Definition: rz-diff.c:128
bool use_utf8
Definition: rz_cons.h:559

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, diff_hex_view_t::buffer_a, diff_hex_view_t::buffer_b, diff_hex_view_t::canvas, diff_hex_view_t::colors, diff_hex_view_t::column_descr, DIFF_HEX_16, DIFF_HEX_32, diff_hexdump_line(), diff_io_t::filename, diff_io_t::filesize, h, diff_screen_t::height, height, diff_io_t::io, diff_hex_view_t::io_a, diff_hex_view_t::io_b, diff_colors_t::legenda, len_draw_hexdump(), diff_hex_view_t::line, setup::line, NULL, offset_len(), p, PFMT64x, pos, diff_colors_t::reset, RUNE_ARROW_DOWN, RUNE_ARROW_LEFT, RUNE_ARROW_RIGHT, RUNE_ARROW_UP, rz_cons_canvas_box(), rz_cons_canvas_clear(), rz_cons_canvas_fill(), rz_cons_canvas_gotoxy(), rz_cons_canvas_print(), rz_cons_canvas_write(), rz_cons_clear(), rz_cons_flush(), rz_cons_goto_origin_reset(), rz_cons_singleton(), rz_io_pread_at(), RZ_MAX, RZ_SYS_DIR, rz_sys_usleep(), diff_hex_view_t::screen, seek_min_shift(), shift(), show_help(), diff_hex_view_t::size_a, diff_hex_view_t::size_b, snprintf, rz_cons_t::use_utf8, ut64(), diff_screen_t::width, and width.

Referenced by rz_diff_hex_visual(), and rz_diff_resize_buffer().

◆ rz_diff_entries_new()

static RzDiff* rz_diff_entries_new ( DiffFile dfile_a,
DiffFile dfile_b 
)
static

Definition at line 993 of file rz-diff.c.

993  {
994  RzList *list_a = NULL;
995  RzList *list_b = NULL;
996 
997  list_a = rz_diff_file_get(dfile_a, entries);
998  if (!list_a) {
999  rz_diff_error_ret(NULL, "cannot get entries from '%s'\n", dfile_a->dio->filename);
1000  }
1001 
1002  list_b = rz_diff_file_get(dfile_b, entries);
1003  if (!list_b) {
1004  rz_diff_error_ret(NULL, "cannot get entries from '%s'\n", dfile_b->dio->filename);
1005  }
1006 
1009 
1010  RzDiffMethods methods = {
1012  .elem_hash = (RzDiffMethodElemHash)entry_hash,
1013  .compare = (RzDiffMethodCompare)entry_compare,
1014  .stringify = (RzDiffMethodStringify)entry_stringify,
1015  .ignore = NULL,
1016  };
1017 
1018  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
1019 }
RzList * entries(RzBinFile *bf)
Definition: bin_ne.c:98
static void entry_stringify(const RzBinAddr *elem, RzStrBuf *sb)
Definition: rz-diff.c:965
static ut32 entry_hash(const RzBinAddr *elem)
Definition: rz-diff.c:942
static int entry_compare(const RzBinAddr *a, const RzBinAddr *b)
Definition: rz-diff.c:952

References diff_file_t::dio, rz_diff_methods_t::elem_at, entries(), entry_compare(), entry_hash(), entry_stringify(), diff_io_t::filename, NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), and rz_list_sort().

Referenced by rz_diff_unified_files().

◆ rz_diff_fields_new()

static RzDiff* rz_diff_fields_new ( DiffFile dfile_a,
DiffFile dfile_b,
bool  compare_addr 
)
static

Definition at line 1229 of file rz-diff.c.

1229  {
1230  RzList *list_a = NULL;
1231  RzList *list_b = NULL;
1232 
1233  list_a = rz_diff_file_get(dfile_a, fields);
1234  if (!list_a) {
1235  rz_diff_error_ret(NULL, "cannot get fields from '%s'\n", dfile_a->dio->filename);
1236  }
1237 
1238  list_b = rz_diff_file_get(dfile_b, fields);
1239  if (!list_b) {
1240  rz_diff_error_ret(NULL, "cannot get fields from '%s'\n", dfile_b->dio->filename);
1241  }
1242 
1245 
1246  RzDiffMethods methods = {
1248  .elem_hash = (RzDiffMethodElemHash)(compare_addr ? field_hash_addr : field_hash),
1250  .stringify = (RzDiffMethodStringify)(compare_addr ? field_stringify_addr : field_stringify),
1251  .ignore = NULL,
1252  };
1253 
1254  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
1255 }
const aarch64_field fields[]
Definition: aarch64-opc.c:205
static ut32 field_hash_addr(const RzBinField *elem)
Definition: rz-diff.c:1182
static int field_compare_addr(const RzBinField *a, const RzBinField *b)
Definition: rz-diff.c:1192
static ut32 field_hash(const RzBinField *elem)
Definition: rz-diff.c:1212
static int field_compare(const RzBinField *a, const RzBinField *b)
Definition: rz-diff.c:1218
static void field_stringify(const RzBinField *elem, RzStrBuf *sb)
Definition: rz-diff.c:1225
static void field_stringify_addr(const RzBinField *elem, RzStrBuf *sb)
Definition: rz-diff.c:1207

References compare(), diff_file_t::dio, rz_diff_methods_t::elem_at, field_compare(), field_compare_addr(), field_hash(), field_hash_addr(), field_stringify(), field_stringify_addr(), fields, diff_io_t::filename, NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), and rz_list_sort().

Referenced by rz_diff_unified_files().

◆ rz_diff_file_close()

static void rz_diff_file_close ( DiffFile file)
static

Definition at line 662 of file rz-diff.c.

662  {
663  // plugin and file are freed by rz_bin_free
664  rz_bin_free(file->bin);
665  rz_diff_io_close(file->dio);
666 }
RZ_API void rz_bin_free(RzBin *bin)
Definition: bin.c:440
static void rz_diff_io_close(DiffIO *dio)
Definition: rz-diff.c:439
Definition: gzappend.c:170

References rz_bin_free(), and rz_diff_io_close().

Referenced by rz_diff_unified_files().

◆ rz_diff_file_open()

static bool rz_diff_file_open ( DiffFile dfile,
const char *  filename 
)
static

Definition at line 617 of file rz-diff.c.

617  {
618  memset((void *)dfile, 0, sizeof(DiffFile));
619  RzBinOptions opt = { 0 };
620  RzBinFile *file = NULL;
621  RzBin *bin = NULL;
622  DiffIO *dio = NULL;
623 
624  dio = rz_diff_io_open(filename);
625  if (!dio) {
626  goto rz_diff_file_open_bad;
627  }
628 
629  bin = rz_bin_new();
630  if (!bin) {
631  rz_diff_error("cannot allocate bin\n");
632  goto rz_diff_file_open_bad;
633  }
634 
635  rz_io_bind(dio->io, &bin->iob);
636 
637  // TODO: no RzConfig ???
638  rz_bin_options_init(&opt, dio->io->desc->fd, 0, 0, false);
639  opt.obj_opts.elf_load_sections = true;
640  opt.obj_opts.elf_checks_sections = true;
641  opt.obj_opts.elf_checks_segments = true;
642  opt.sz = rz_io_desc_size(dio->io->desc);
643 
644  file = rz_bin_open_io(bin, &opt);
645  if (!file) {
646  rz_diff_error("cannot open bin file via io\n");
647  goto rz_diff_file_open_bad;
648  }
649 
650  dfile->plugin = rz_bin_file_cur_plugin(file);
651  dfile->file = file;
652  dfile->bin = bin;
653  dfile->dio = dio;
654  return true;
655 
656 rz_diff_file_open_bad:
657  rz_bin_free(bin);
658  rz_diff_io_close(dio);
659  return false;
660 }
RZ_API RzBinPlugin * rz_bin_file_cur_plugin(RzBinFile *bf)
Definition: bfile.c:348
RZ_API RzBin * rz_bin_new(void)
Definition: bin.c:716
RZ_API RzBinFile * rz_bin_open_io(RzBin *bin, RzBinOptions *opt)
Definition: bin.c:283
RZ_API void rz_bin_options_init(RzBinOptions *opt, int fd, ut64 baseaddr, ut64 loadaddr, bool patch_relocs)
Definition: bin.c:75
static DiffIO * rz_diff_io_open(const char *file)
Definition: rz-diff.c:404
RZ_API ut64 rz_io_desc_size(RzIODesc *desc)
Definition: io_desc.c:224
RZ_API void rz_io_bind(RzIO *io, RzIOBind *bnd)
Definition: io.c:550
Definition: malloc.c:26
XX curplugin == o->plugin.
Definition: rz_bin.h:298
int fd
Definition: rz_io.h:96
struct rz_io_desc_t * desc
Definition: rz_io.h:60
static int file
Definition: z80asm.c:58

References diff_file_t::bin, rz_io_t::desc, diff_file_t::dio, rz_io_desc_t::fd, file, diff_file_t::file, diff_io_t::io, memset(), NULL, diff_file_t::plugin, rz_bin_file_cur_plugin(), rz_bin_free(), rz_bin_new(), rz_bin_open_io(), rz_bin_options_init(), rz_diff_error, rz_diff_io_close(), rz_diff_io_open(), rz_io_bind(), and rz_io_desc_size().

Referenced by rz_diff_unified_files().

◆ rz_diff_get_colors()

static void rz_diff_get_colors ( DiffColors dcolors,
RzConsContext ctx,
bool  colors 
)
static

Definition at line 396 of file rz-diff.c.

396  {
397  dcolors->number = colors ? ctx->pal.diff_unknown : "";
398  dcolors->match = colors ? ctx->pal.diff_match : "";
399  dcolors->unmatch = colors ? ctx->pal.diff_unmatch : Color_INVERT;
400  dcolors->legenda = colors ? ctx->pal.comment : "";
401  dcolors->reset = Color_RESET;
402 }
struct @219 colors[]
#define Color_RESET
Definition: rz_cons.h:617
#define Color_INVERT
Definition: rz_cons.h:606

References Color_INVERT, Color_RESET, colors, diff_colors_t::legenda, diff_colors_t::match, diff_colors_t::number, diff_colors_t::reset, and diff_colors_t::unmatch.

Referenced by rz_diff_hex_visual().

◆ rz_diff_graphs_files()

static bool rz_diff_graphs_files ( DiffContext ctx)
static

Definition at line 1413 of file rz-diff.c.

1413  {
1414  bool success = false;
1415  RzCoreFile *a = NULL;
1416  RzCoreFile *b = NULL;
1417 
1418  a = rz_diff_load_file_with_core(ctx->file_a, ctx->architecture, ctx->arch_bits, ctx->evars, ctx->colors);
1419  if (!a) {
1420  goto rz_diff_graphs_files_bad;
1421  }
1422 
1423  b = rz_diff_load_file_with_core(ctx->file_b, ctx->architecture, ctx->arch_bits, ctx->evars, ctx->colors);
1424  if (!b) {
1425  goto rz_diff_graphs_files_bad;
1426  }
1427 
1428  if (ctx->type == DIFF_TYPE_PLOTDIFF) {
1429  ut64 address_a = 0;
1430  ut64 address_b = 0;
1431 
1432  if (!convert_offset_from_input(a->core, ctx->input_a, &address_a)) {
1433  rz_diff_error("cannot convert '%s' into an offset\n", ctx->input_a);
1434  goto rz_diff_graphs_files_bad;
1435  }
1436 
1437  if (!convert_offset_from_input(b->core, ctx->input_b, &address_b)) {
1438  rz_diff_error("cannot convert '%s' into an offset\n", ctx->input_b);
1439  goto rz_diff_graphs_files_bad;
1440  }
1441 
1442  if (ctx->analyze_all) {
1443  if (!rz_core_analysis_everything(a->core, false, NULL)) {
1444  rz_diff_error("cannot analyze binary '%s'\n", ctx->file_a);
1445  goto rz_diff_graphs_files_bad;
1446  }
1447  if (!rz_core_analysis_everything(b->core, false, NULL)) {
1448  rz_diff_error("cannot analyze binary '%s'\n", ctx->file_b);
1449  goto rz_diff_graphs_files_bad;
1450  }
1451  } else {
1452  bool analyze_recursively = rz_config_get_i(a->core->config, "analysis.calls");
1453  if (!rz_core_analysis_function_add(a->core, NULL, address_a, analyze_recursively)) {
1454  rz_diff_error("cannot find function at '%s' in '%s' \n", ctx->input_a, ctx->file_a);
1455  goto rz_diff_graphs_files_bad;
1456  }
1457  if (!rz_core_analysis_function_add(b->core, NULL, address_b, analyze_recursively)) {
1458  rz_diff_error("cannot find function at '%s' in '%s' \n", ctx->input_b, ctx->file_b);
1459  goto rz_diff_graphs_files_bad;
1460  }
1461  }
1462 
1463  if (!rz_core_gdiff_function_2_files(a->core, b->core, address_a, address_b)) {
1464  rz_diff_error("cannot diff graphs with inputs '%s' with '%s'\n", ctx->input_a, ctx->input_b);
1465  goto rz_diff_graphs_files_bad;
1466  }
1467  rz_core_diff_show_function(a->core, b->core, address_a, ctx->mode == DIFF_MODE_JSON);
1468  } else {
1469  if (!rz_core_analysis_everything(a->core, false, NULL)) {
1470  rz_diff_error("cannot analyze binary '%s'\n", ctx->file_a);
1471  goto rz_diff_graphs_files_bad;
1472  }
1473  if (!rz_core_analysis_everything(b->core, false, NULL)) {
1474  rz_diff_error("cannot analyze binary '%s'\n", ctx->file_b);
1475  goto rz_diff_graphs_files_bad;
1476  }
1477  if (!rz_core_gdiff_2_files(a->core, b->core)) {
1478  rz_diff_error("cannot diff all graphs\n");
1479  goto rz_diff_graphs_files_bad;
1480  }
1481  rz_core_diff_show(a->core, b->core, ctx->mode == DIFF_MODE_JSON);
1482  }
1483 
1484  success = true;
1485 
1486 rz_diff_graphs_files_bad:
1487  rz_core_free(a ? a->core : NULL);
1488  rz_core_free(b ? b->core : NULL);
1489  return success;
1490 }
RZ_API bool rz_core_analysis_function_add(RzCore *core, const char *name, ut64 addr, bool analyze_recursively)
Definition: canalysis.c:5298
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API bool rz_core_gdiff_function_2_files(RzCore *c, RzCore *c2, ut64 addr, ut64 addr2)
Calculates basic block differences of 2 functions within 2 files.
Definition: gdiff.c:47
RZ_API bool rz_core_diff_show_function(RzCore *core, RzCore *core2, ut64 addr1, bool json)
Generate a json or dot output of the graph and its data.
Definition: gdiff.c:574
RZ_API void rz_core_diff_show(RzCore *c, RzCore *c2, bool json)
Definition: gdiff.c:161
RZ_API bool rz_core_gdiff_2_files(RzCore *c, RzCore *c2)
Calculates basic block differences of all functions within 2 files.
Definition: gdiff.c:89
static bool convert_offset_from_input(RzCore *core, const char *input, ut64 *offset)
Definition: rz-diff.c:1398

References a, b, convert_offset_from_input(), DIFF_MODE_JSON, DIFF_TYPE_PLOTDIFF, NULL, rz_config_get_i(), rz_core_analysis_everything(), rz_core_analysis_function_add(), rz_core_diff_show(), rz_core_diff_show_function(), rz_core_free(), rz_core_gdiff_2_files(), rz_core_gdiff_function_2_files(), rz_diff_error, rz_diff_load_file_with_core(), and ut64().

Referenced by rz_main_rz_diff().

◆ rz_diff_hex_visual()

static bool rz_diff_hex_visual ( DiffContext ctx)
static

Definition at line 2027 of file rz-diff.c.

2027  {
2028  RzCons *console = NULL;
2029  DiffIO *io_a = NULL;
2030  DiffIO *io_b = NULL;
2031  RzConsCanvas *canvas = NULL;
2032  DiffHexView hview;
2033  bool draw_visual = true;
2034  bool show_help = false;
2035  int read, pressed;
2036  int height = ctx->screen.width;
2037  int width = ctx->screen.height;
2038  ut64 size_a = 0;
2039  ut64 size_b = 0;
2040 
2041  hview.line = NULL;
2042  hview.buffer_a = NULL;
2043  hview.buffer_b = NULL;
2044 
2045  RzCore *core = rz_core_new();
2046  if (!core) {
2047  rz_diff_error("cannot allocate core\n");
2048  goto rz_diff_hex_visual_fail;
2049  }
2050 
2051  rz_core_parse_rizinrc(core);
2052 
2053  console = rz_cons_singleton();
2054  if (!console) {
2055  rz_diff_error("cannot get console.\n");
2056  goto rz_diff_hex_visual_fail;
2057  }
2058 
2059  rz_cons_set_interactive(false);
2060 
2061  io_a = rz_diff_io_open(ctx->file_a);
2062  if (!io_a) {
2063  goto rz_diff_hex_visual_fail;
2064  }
2065 
2066  io_b = rz_diff_io_open(ctx->file_b);
2067  if (!io_b) {
2068  goto rz_diff_hex_visual_fail;
2069  }
2070 
2071  if (width < 1 && height < 1) {
2073  if (width < 1 && height < 1) {
2074  rz_diff_error("invalid screen size; use -S WxH to define the sizes.\n");
2075  goto rz_diff_hex_visual_fail;
2076  }
2077  }
2078 
2079  canvas = rz_cons_canvas_new(width, height);
2080  if (!canvas) {
2081  rz_diff_error("cannot allocate canvas. try to use -S WxH to define the sizes.\n");
2082  goto rz_diff_hex_visual_fail;
2083  }
2084 
2085  size_a = ((width / 2) * (height - 2));
2086  size_b = ((width / 2) * (height - 2));
2087 
2088  canvas->color = true;
2089  canvas->linemode = 1;
2090 
2091  st64 video_size = width;
2092  video_size *= height;
2093  hview.line = malloc(video_size);
2094  if (!hview.line) {
2095  rz_diff_error("cannot allocate line buffer.\n");
2096  goto rz_diff_hex_visual_fail;
2097  }
2098  hview.buffer_a = malloc(size_a);
2099  if (!hview.buffer_a) {
2100  rz_diff_error("cannot allocate buffer for %s.\n", io_a->filename);
2101  goto rz_diff_hex_visual_fail;
2102  }
2103  hview.buffer_b = malloc(size_b);
2104  if (!hview.buffer_b) {
2105  rz_diff_error("cannot allocate buffer for %s.\n", io_b->filename);
2106  goto rz_diff_hex_visual_fail;
2107  }
2108 
2109  hview.size_a = size_a;
2110  hview.size_b = size_b;
2111  hview.io_a = io_a;
2112  hview.io_b = io_b;
2113  hview.canvas = canvas;
2114  hview.screen.width = width;
2115  hview.screen.height = height;
2116  hview.address_a = 0;
2117  hview.address_b = 0;
2118  hview.column_descr = true;
2119  rz_diff_get_colors(&hview.colors, console->context, ctx->colors);
2120 
2121  rz_cons_show_cursor(false);
2122  rz_cons_enable_mouse(false);
2123 
2124  console->event_data = &hview;
2126 
2127  int seekmin = 0;
2128  while (draw_visual && !rz_cons_is_breaked()) {
2129  if (!rz_diff_draw_tui(&hview, show_help)) {
2130  break;
2131  }
2132  seekmin = seek_min_value(&hview);
2133  read = rz_cons_readchar();
2134  pressed = rz_cons_arrow_to_hjkl(read);
2135 
2136  if (show_help && (pressed == 'q' || pressed == 'Q')) {
2137  // allow to close the help without closing the util
2138  pressed = 0;
2139  }
2140 
2141  show_help = false;
2142  switch (pressed) {
2143  case '0':
2144  hview.column_descr = !hview.column_descr;
2145  break;
2146  case '?':
2147  show_help = true;
2148  break;
2149  case ':':
2150  prompt_offset_and_seek(&hview, seekmin);
2151  break;
2152  case '3':
2153  prompt_offset_and_seek_file(&hview, seekmin, true);
2154  break;
2155  case '4':
2156  prompt_offset_and_seek_file(&hview, seekmin, false);
2157  break;
2158  case '9':
2159  hview.address_a = hview.address_b = RZ_MIN(hview.address_a, hview.address_b);
2160  break;
2161  case 'G':
2162  case 'g':
2163  hview.address_a = io_a->filesize - seekmin;
2164  hview.address_b = io_b->filesize - seekmin;
2165  break;
2166  case 'B':
2167  case 'b':
2168  hview.address_a = 0;
2169  hview.address_b = 0;
2170  break;
2171  case 'A':
2172  case 'a':
2173  hview.address_a--;
2174  break;
2175  case 'N':
2176  case 'n':
2177  find_next_diff(&hview, seekmin);
2178  break;
2179  case 'M':
2180  case 'm':
2181  find_prev_diff(&hview, seekmin);
2182  break;
2183  case 'Z':
2184  case 'z':
2185  hview.address_a++;
2186  break;
2187  case 'D':
2188  case 'd':
2189  hview.address_b--;
2190  break;
2191  case 'C':
2192  case 'c':
2193  hview.address_b++;
2194  break;
2195  /* ARROWS */
2196  case '1':
2197  hview.address_a -= (seekmin * (height - 2));
2198  hview.address_b -= (seekmin * (height - 2));
2199  break;
2200  case '2':
2201  hview.address_a += (seekmin * (height - 2));
2202  hview.address_b += (seekmin * (height - 2));
2203  break;
2204  case 'K':
2205  case 'k':
2206  hview.address_a -= seekmin;
2207  hview.address_b -= seekmin;
2208  break;
2209  case 'J':
2210  case 'j':
2211  hview.address_a += seekmin;
2212  hview.address_b += seekmin;
2213  break;
2214  case 'L':
2215  case 'l':
2216  hview.address_a--;
2217  hview.address_b--;
2218  break;
2219  case 'H':
2220  case 'h':
2221  hview.address_a++;
2222  hview.address_b++;
2223  break;
2224  case -1: // EOF
2225  case 'Q':
2226  case 'q':
2227  draw_visual = false;
2228  default:
2229  break;
2230  }
2231  }
2232  canvas = hview.canvas;
2233  console->event_data = NULL;
2234  console->event_resize = NULL;
2235 
2236  rz_cons_show_cursor(true);
2238  rz_cons_clear();
2239  rz_cons_print(Color_RESET_TERMINAL);
2240  rz_cons_flush();
2241 
2242 rz_diff_hex_visual_fail:
2243  free(hview.line);
2244  free(hview.buffer_a);
2245  free(hview.buffer_b);
2246  rz_cons_canvas_free(canvas);
2247  rz_diff_io_close(io_a);
2248  rz_diff_io_close(io_b);
2249  rz_core_free(core);
2250  rz_cons_free();
2251  return true;
2252 }
RZ_API RzConsCanvas * rz_cons_canvas_new(int w, int h)
Definition: canvas.c:223
RZ_API void rz_cons_canvas_free(RzConsCanvas *c)
Definition: canvas.c:150
RZ_API void rz_core_parse_rizinrc(RzCore *r)
Definition: cconfig.c:3704
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API void rz_cons_set_interactive(bool x)
Definition: cons.c:1724
RZ_API void rz_cons_show_cursor(int cursor)
Definition: cons.c:1581
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API RzCons * rz_cons_free(void)
Definition: cons.c:658
RZ_API int rz_cons_arrow_to_hjkl(int ch)
Definition: input.c:78
RZ_API int rz_cons_readchar(void)
Definition: input.c:619
RZ_API RzCore * rz_core_new(void)
Definition: core.c:866
static void rz_diff_get_colors(DiffColors *dcolors, RzConsContext *ctx, bool colors)
Definition: rz-diff.c:396
static int seek_min_value(DiffHexView *hview)
Definition: rz-diff.c:1612
static void prompt_offset_and_seek(DiffHexView *hview, ut64 minseek)
Definition: rz-diff.c:1854
static bool rz_diff_draw_tui(DiffHexView *hview, bool show_help)
Definition: rz-diff.c:1632
static void find_prev_diff(DiffHexView *hview, ut64 seek)
Definition: rz-diff.c:1967
static void prompt_offset_and_seek_file(DiffHexView *hview, ut64 minseek, bool is_file0)
Definition: rz-diff.c:1877
static void rz_diff_resize_buffer(DiffHexView *hview)
Definition: rz-diff.c:2003
static void find_next_diff(DiffHexView *hview, ut64 seek)
Definition: rz-diff.c:1909
void * malloc(size_t size)
Definition: malloc.c:123
void(* RzConsEvent)(void *)
Definition: rz_cons.h:346
#define Color_RESET_TERMINAL
Definition: rz_cons.h:615
RzConsEvent event_resize
Definition: rz_cons.h:522
void * event_data
Definition: rz_cons.h:523
RzConsContext * context
Definition: rz_cons.h:502
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References diff_hex_view_t::address_a, diff_hex_view_t::address_b, diff_hex_view_t::buffer_a, diff_hex_view_t::buffer_b, diff_hex_view_t::canvas, rz_cons_canvas_t::color, Color_RESET_TERMINAL, diff_hex_view_t::colors, diff_hex_view_t::column_descr, rz_cons_t::context, rz_cons_t::event_data, rz_cons_t::event_resize, diff_io_t::filename, diff_io_t::filesize, find_next_diff(), find_prev_diff(), free(), diff_screen_t::height, height, diff_hex_view_t::io_a, diff_hex_view_t::io_b, diff_hex_view_t::line, rz_cons_canvas_t::linemode, malloc(), NULL, prompt_offset_and_seek(), prompt_offset_and_seek_file(), read(), rz_cons_arrow_to_hjkl(), rz_cons_canvas_free(), rz_cons_canvas_new(), rz_cons_clear(), rz_cons_enable_mouse(), rz_cons_flush(), rz_cons_free(), rz_cons_get_size(), rz_cons_goto_origin_reset(), rz_cons_is_breaked(), rz_cons_readchar(), rz_cons_set_interactive(), rz_cons_show_cursor(), rz_cons_singleton(), rz_core_free(), rz_core_new(), rz_core_parse_rizinrc(), rz_diff_draw_tui(), rz_diff_error, rz_diff_get_colors(), rz_diff_io_close(), rz_diff_io_open(), rz_diff_resize_buffer(), RZ_MIN, diff_hex_view_t::screen, seek_min_value(), show_help(), diff_hex_view_t::size_a, diff_hex_view_t::size_b, st64, ut64(), diff_screen_t::width, and width.

Referenced by rz_main_rz_diff().

◆ rz_diff_imports_new()

static RzDiff* rz_diff_imports_new ( DiffFile dfile_a,
DiffFile dfile_b 
)
static

Definition at line 698 of file rz-diff.c.

698  {
699  RzList *list_a = NULL;
700  RzList *list_b = NULL;
701 
702  list_a = rz_diff_file_get(dfile_a, imports);
703  if (!list_a) {
704  rz_diff_error_ret(NULL, "cannot get imports from '%s'\n", dfile_a->dio->filename);
705  }
706 
707  list_b = rz_diff_file_get(dfile_b, imports);
708  if (!list_b) {
709  rz_diff_error_ret(NULL, "cannot get imports from '%s'\n", dfile_b->dio->filename);
710  }
711 
714 
715  RzDiffMethods methods = {
717  .elem_hash = (RzDiffMethodElemHash)import_hash,
720  .ignore = NULL,
721  };
722 
723  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
724 }
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
static int import_compare(const RzBinImport *a, const RzBinImport *b)
Definition: rz-diff.c:690
static void import_stringify(const RzBinImport *elem, RzStrBuf *sb)
Definition: rz-diff.c:685
static ut32 import_hash(const RzBinImport *elem)
Definition: rz-diff.c:678

References diff_file_t::dio, rz_diff_methods_t::elem_at, diff_io_t::filename, import_compare(), import_hash(), import_stringify(), imports(), NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), and rz_list_sort().

Referenced by rz_diff_unified_files().

◆ rz_diff_io_close()

static void rz_diff_io_close ( DiffIO dio)
static

Definition at line 439 of file rz-diff.c.

439  {
440  if (!dio) {
441  return;
442  }
443  rz_io_desc_close(dio->io->desc);
444  rz_io_free(dio->io);
445  free(dio);
446 }
RZ_API void rz_io_free(RzIO *io)
Definition: io.c:126
RZ_API bool rz_io_desc_close(RzIODesc *desc)
Definition: io_desc.c:165

References rz_io_t::desc, free(), diff_io_t::io, rz_io_desc_close(), and rz_io_free().

Referenced by rz_diff_file_close(), rz_diff_file_open(), rz_diff_hex_visual(), and rz_diff_slurp_file().

◆ rz_diff_io_open()

static DiffIO* rz_diff_io_open ( const char *  file)
static

Definition at line 404 of file rz-diff.c.

404  {
405  RzIODesc *desc = NULL;
406  RzIO *io = NULL;
407  DiffIO *dio = NULL;
408 
409  dio = RZ_NEW0(DiffIO);
410  if (!dio) {
411  rz_diff_error("cannot allocate diff io\n");
412  goto rz_diff_io_open_end;
413  }
414 
415  io = rz_io_new();
416  if (!io) {
417  rz_diff_error("cannot allocate io\n");
418  goto rz_diff_io_open_end;
419  }
420 
421  desc = rz_io_open_nomap(io, file, RZ_PERM_R, 0);
422  if (!desc) {
423  rz_diff_error("cannot open file '%s'\n", file);
424  goto rz_diff_io_open_end;
425  }
426 
427  dio->filename = file;
428  dio->filesize = rz_io_desc_size(desc);
429  dio->io = io;
430  return dio;
431 
432 rz_diff_io_open_end:
434  rz_io_free(io);
435  free(dio);
436  return NULL;
437 }
const char * desc
Definition: bin_vsf.c:19
RZ_API RzIODesc * rz_io_open_nomap(RzIO *io, const char *uri, int flags, int mode)
Definition: io.c:145
RZ_API RzIO * rz_io_new(void)
Definition: io.c:110
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
Definition: rz_io.h:59

References desc, file, diff_io_t::filename, diff_io_t::filesize, free(), diff_io_t::io, NULL, rz_diff_error, rz_io_desc_close(), rz_io_desc_size(), rz_io_free(), rz_io_new(), rz_io_open_nomap(), RZ_NEW0, and RZ_PERM_R.

Referenced by rz_diff_file_open(), rz_diff_hex_visual(), and rz_diff_slurp_file().

◆ rz_diff_is_file()

static bool rz_diff_is_file ( const char *  file)
static

Definition at line 244 of file rz-diff.c.

244  {
245  if (IS_NULLSTR(file)) {
246  rz_diff_error_ret(false, "cannot open a file without a name.\n");
247  }
248  if (rz_file_is_directory(file)) {
249  rz_diff_error_ret(false, "cannot open directories (%s).\n", file);
250  }
251  return true;
252 }
RZ_API bool rz_file_is_directory(const char *str)
Definition: file.c:167
#define IS_NULLSTR(x)
Definition: rz_str_util.h:4

References IS_NULLSTR, rz_diff_error_ret, and rz_file_is_directory().

Referenced by rz_diff_parse_arguments().

◆ rz_diff_libraries_new()

static RzDiff* rz_diff_libraries_new ( DiffFile dfile_a,
DiffFile dfile_b 
)
static

Definition at line 1037 of file rz-diff.c.

1037  {
1038  RzList *list_a = NULL;
1039  RzList *list_b = NULL;
1040 
1041  list_a = rz_diff_file_get(dfile_a, libs);
1042  if (!list_a) {
1043  rz_diff_error_ret(NULL, "cannot get libraries from '%s'\n", dfile_a->dio->filename);
1044  }
1045 
1046  list_b = rz_diff_file_get(dfile_b, libs);
1047  if (!list_b) {
1048  rz_diff_error_ret(NULL, "cannot get libraries from '%s'\n", dfile_b->dio->filename);
1049  }
1050 
1053 
1054  RzDiffMethods methods = {
1056  .elem_hash = (RzDiffMethodElemHash)libs_hash,
1057  .compare = (RzDiffMethodCompare)libs_compare,
1058  .stringify = (RzDiffMethodStringify)libs_stringify,
1059  .ignore = NULL,
1060  };
1061 
1062  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
1063 }
static RzList * libs(RzBinFile *bf)
Definition: bin_coff.c:379
static ut32 libs_hash(const char *elem)
Definition: rz-diff.c:1023
static void libs_stringify(const char *elem, RzStrBuf *sb)
Definition: rz-diff.c:1033
static int libs_compare(const char *a, const char *b)
Definition: rz-diff.c:1027

References diff_file_t::dio, rz_diff_methods_t::elem_at, diff_io_t::filename, libs(), libs_compare(), libs_hash(), libs_stringify(), NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), and rz_list_sort().

Referenced by rz_diff_unified_files().

◆ rz_diff_list_elem_at()

static const void* rz_diff_list_elem_at ( const RzList array,
ut32  index 
)
static

Definition at line 672 of file rz-diff.c.

672  {
673  return rz_list_get_n(array, index);
674 }
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574

References rz_list_get_n().

Referenced by rz_diff_classes_new(), rz_diff_entries_new(), rz_diff_fields_new(), rz_diff_imports_new(), rz_diff_libraries_new(), rz_diff_sections_new(), rz_diff_strings_new(), and rz_diff_symbols_new().

◆ rz_diff_load_file_with_core()

static RzCoreFile* rz_diff_load_file_with_core ( const char *  filename,
const char *  architecture,
ut32  arch_bits,
RzList evars,
bool  colors 
)
static

Definition at line 554 of file rz-diff.c.

554  {
555  RzCore *core = NULL;
556  RzCoreFile *cfile = NULL;
557  RzBinFile *bfile = NULL;
558  RzListIter *it;
559  char *config;
560 
561  core = rz_core_new();
562  if (!core) {
563  rz_diff_error("cannot allocate core\n");
564  goto rz_diff_load_file_with_core_fail;
565  }
566  rz_core_loadlibs(core, RZ_CORE_LOADLIBS_ALL);
567 
568  rz_config_set_i(core->config, "scr.color", colors ? 1 : 0);
569  rz_config_set_b(core->config, "scr.interactive", false);
570  rz_config_set_b(core->config, "cfg.debug", false);
571  core->print->scr_prompt = false;
572  cfile = rz_core_file_open(core, filename, 0, 0);
573  if (!cfile) {
574  rz_diff_error("cannot open file '%s'\n", filename);
575  goto rz_diff_load_file_with_core_fail;
576  }
577 
578  if (!rz_core_bin_load(core, NULL, UT64_MAX)) {
579  rz_diff_error("cannot load file '%s'\n", filename);
580  goto rz_diff_load_file_with_core_fail;
581  }
582 
583  if (!rz_core_bin_update_arch_bits(core)) {
584  rz_diff_error("cannot set architecture with bits\n");
585  goto rz_diff_load_file_with_core_fail;
586  }
587 
588  bfile = core_get_file(cfile);
589  if (!bfile) {
590  rz_diff_error("cannot get architecture with bits\n");
591  goto rz_diff_load_file_with_core_fail;
592  }
593 
594  if (rz_list_empty(bfile->o->maps)) {
595  rz_config_set_i(core->config, "io.va", false);
596  }
597 
598  if (architecture) {
599  rz_config_set(core->config, "asm.arch", architecture);
600  }
601 
602  if (arch_bits) {
603  rz_config_set_i(core->config, "asm.bits", arch_bits);
604  }
605 
606  rz_list_foreach (evars, it, config) {
607  rz_config_eval(core->config, config);
608  }
609 
610  return cfile;
611 
612 rz_diff_load_file_with_core_fail:
613  rz_core_free(core);
614  return NULL;
615 }
RZ_API int rz_core_bin_update_arch_bits(RzCore *r)
Definition: cbin.c:4503
RZ_API RZ_BORROW RzCoreFile * rz_core_file_open(RZ_NONNULL RzCore *r, RZ_NONNULL const char *file, int flags, ut64 loadaddr)
Tries to open the file as is, otherwise tries as is a compilation of files.
Definition: cfile.c:1182
RZ_API bool rz_core_bin_load(RZ_NONNULL RzCore *r, RZ_NULLABLE const char *filenameuri, ut64 baddr)
Definition: cfile.c:942
RZ_API bool rz_config_eval(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *str)
Sets the configuration variable and its value passed as argument.
Definition: config.c:575
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API RzConfigNode * rz_config_set_b(RzConfig *cfg, RZ_NONNULL const char *name, bool value)
Definition: config.c:201
struct config_s config
static RzBinFile * core_get_file(RzCoreFile *cfile)
Definition: rz-diff.c:550
RZ_API int rz_core_loadlibs(RzCore *core, int where)
Definition: libs.c:119
#define UT64_MAX
Definition: rz_types_base.h:86
RzBinObject * o
Definition: rz_bin.h:305
RzList * maps
Definition: rz_bin.h:266
RzPrint * print
Definition: rz_core.h:327
RzConfig * config
Definition: rz_core.h:300
bool scr_prompt
Definition: rz_print.h:121

References benchmark::cfile, colors, rz_core_t::config, core_get_file(), rz_bin_object_t::maps, NULL, rz_bin_file_t::o, rz_core_t::print, rz_config_eval(), rz_config_set(), rz_config_set_b(), rz_config_set_i(), rz_core_bin_load(), rz_core_bin_update_arch_bits(), rz_core_file_open(), rz_core_free(), rz_core_loadlibs(), rz_core_new(), rz_diff_error, rz_print_t::scr_prompt, and UT64_MAX.

Referenced by execute_command(), and rz_diff_graphs_files().

◆ rz_diff_parse_arguments()

static void rz_diff_parse_arguments ( int  argc,
const char **  argv,
DiffContext ctx 
)
static

Definition at line 254 of file rz-diff.c.

254  {
255  const char *type = NULL;
256  const char *algorithm = NULL;
257  const char *screen = NULL;
258  memset((void *)ctx, 0, sizeof(DiffContext));
259  ctx->colors = true;
260  ctx->evars = rz_list_newf(free);
261 
262  if (!ctx->evars) {
263  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "cannot allocate list for evars");
264  return;
265  }
266 
267  RzGetopt opt;
268  int c;
269  rz_getopt_init(&opt, argc, argv, "hHjqvABCTa:b:e:d:t:0:1:S:");
270  while ((c = rz_getopt_next(&opt)) != -1) {
271  switch (c) {
272  case '0': rz_diff_ctx_set_def(ctx, input_a, NULL, opt.arg); break;
273  case '1': rz_diff_ctx_set_def(ctx, input_b, NULL, opt.arg); break;
274  case 'A': rz_diff_ctx_set_def(ctx, compare_addresses, false, true); break;
275  case 'B': rz_diff_ctx_set_def(ctx, analyze_all, false, true); break;
276  case 'C': rz_diff_ctx_set_def(ctx, colors, true, false); break;
277  case 'T': rz_diff_ctx_set_def(ctx, show_time, false, true); break;
278  case 'a': rz_diff_ctx_set_def(ctx, architecture, NULL, opt.arg); break;
279  case 'b': rz_diff_ctx_set_unsigned(ctx, arch_bits, opt.arg); break;
280  case 'd': rz_diff_set_def(algorithm, NULL, opt.arg); break;
281  case 'h': rz_diff_ctx_set_opt(ctx, DIFF_OPT_HELP); break;
282  case 'j': rz_diff_ctx_set_mode(ctx, DIFF_MODE_JSON); break;
283  case 'q': rz_diff_ctx_set_mode(ctx, DIFF_MODE_QUIET); break;
284  case 't': rz_diff_set_def(type, NULL, opt.arg); break;
285  case 'v': rz_diff_ctx_set_opt(ctx, DIFF_OPT_VERSION); break;
286  case 'S': rz_diff_set_def(screen, NULL, opt.arg); break;
287  case 'H': rz_diff_ctx_set_opt(ctx, DIFF_OPT_HEX_VISUAL); break;
288  case 'e': rz_diff_ctx_add_evar(ctx, opt.arg); break;
289  default:
290  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "unknown flag '%c'\n", c);
291  }
292  }
293 
294  if (ctx->option == DIFF_OPT_HELP ||
295  ctx->option == DIFF_OPT_VERSION) {
296  return;
297  }
298 
299  if (opt.ind >= argc || (argc - opt.ind) != 2) {
300  rz_diff_error_opt(ctx, DIFF_OPT_USAGE, "expected 2 files but got %d.\n", (argc - opt.ind));
301  }
302 
303  ctx->file_a = argv[opt.ind + 0];
304  ctx->file_b = argv[opt.ind + 1];
305 
306  if (!rz_diff_is_file(ctx->file_a) ||
307  !rz_diff_is_file(ctx->file_b)) {
308  ctx->option = DIFF_OPT_USAGE;
309  return;
310  }
311 
312  if (algorithm) {
313  if (type) {
314  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t argument is not compatible with -d.\n");
315  } else if (ctx->show_time) {
316  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -T argument is not compatible with -d.\n");
317  }
318 
320  if (!strcmp(algorithm, "myers")) {
322  } else if (!strcmp(algorithm, "leven")) {
324  } else {
325  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -d argument '%s' is not a recognized algorithm.\n", algorithm);
326  }
327  } else if (type) {
329 
330  if (!strcmp(type, "bytes")) {
332  } else if (!strcmp(type, "lines")) {
334  } else if (!strcmp(type, "functions")) {
335  if (ctx->input_a) {
336  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t '%s' does not support -0.\n", type);
337  } else if (ctx->input_b) {
338  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t '%s' does not support -1.\n", type);
339  }
340  ctx->option = DIFF_OPT_GRAPH;
342  } else if (!strcmp(type, "classes")) {
344  } else if (!strcmp(type, "command")) {
345  if (!ctx->input_a) {
346  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t '%s' requires -0 <command>.\n", type);
347  }
348  if (!ctx->input_b) {
349  ctx->input_b = ctx->input_a;
350  }
352  } else if (!strcmp(type, "entries")) {
354  } else if (!strcmp(type, "fields")) {
356  } else if (!strcmp(type, "graphs")) {
357  if (!ctx->input_a) {
358  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t '%s' requires -0 <fcn name|address>.\n", type);
359  } else if (ctx->input_a && !ctx->input_b) {
360  ctx->input_b = ctx->input_a;
361  }
362  ctx->option = DIFF_OPT_GRAPH;
364  } else if (!strcmp(type, "imports")) {
366  } else if (!strcmp(type, "libraries")) {
368  } else if (!strcmp(type, "sections")) {
370  } else if (!strcmp(type, "strings")) {
372  } else if (!strcmp(type, "symbols")) {
374  } else {
375  rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t argument '%s' is not a recognized type.\n", type);
376  }
377  } else if (screen) {
378  const char *hp = NULL;
379  if (!(hp = strchr(screen, 'x'))) {
380  rz_diff_error_opt(ctx, DIFF_OPT_USAGE, "invalid format for -S; example 120x20 where width=120 and height=20.\n");
381  }
382  ut64 height = strtoull(screen, NULL, 0);
383  ut64 width = strtoull(hp + 1, NULL, 0);
384  if (width < 1 || width > 0xFFFF || height < 1 || height > 0xFFFF) {
385  rz_diff_error_opt(ctx, DIFF_OPT_USAGE, "invalid format for -S; example 120x20 where width=120 and height=20.\n");
386  } else if (width < 20 || height < 120) {
387  rz_diff_error_opt(ctx, DIFF_OPT_USAGE, "Min width=120, Min height=20.\n");
388  }
389  ctx->screen.width = (int)width;
390  ctx->screen.height = (int)height;
391  } else if (ctx->option == DIFF_OPT_UNKNOWN) {
392  rz_diff_error_opt(ctx, DIFF_OPT_USAGE, "option -t or -d is required to be specified.\n");
393  }
394 }
#define rz_diff_error_opt(x, o, f,...)
Definition: rz-diff.c:141
#define rz_diff_ctx_set_dist(x, t)
Definition: rz-diff.c:190
#define rz_diff_ctx_set_def(x, k, d, v)
Definition: rz-diff.c:157
#define rz_diff_set_def(x, d, v)
Definition: rz-diff.c:148
#define rz_diff_ctx_set_mode(x, m)
Definition: rz-diff.c:192
#define rz_diff_ctx_add_evar(x, o)
Definition: rz-diff.c:181
#define rz_diff_ctx_set_opt(x, o)
Definition: rz-diff.c:193
#define rz_diff_ctx_set_unsigned(x, k, i)
Definition: rz-diff.c:173
static bool rz_diff_is_file(const char *file)
Definition: rz-diff.c:244
#define rz_diff_ctx_set_type(x, t)
Definition: rz-diff.c:191
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
int type
Definition: mipsasm.c:17
RZ_API void rz_getopt_init(RzGetopt *go, int argc, const char **argv, const char *ostr)
Definition: getopt.c:17
RZ_API int rz_getopt_next(RzGetopt *opt)
Definition: getopt.c:29
static int
Definition: sfsocketcall.h:114
const char * arg
Definition: rz_getopt.h:15

References rz_getopt_t::arg, argv, c, colors, DIFF_DISTANCE_LEVENSHTEIN, DIFF_DISTANCE_MYERS, DIFF_MODE_JSON, DIFF_MODE_QUIET, DIFF_OPT_DISTANCE, DIFF_OPT_ERROR, DIFF_OPT_GRAPH, DIFF_OPT_HELP, DIFF_OPT_HEX_VISUAL, DIFF_OPT_UNIFIED, DIFF_OPT_UNKNOWN, DIFF_OPT_USAGE, DIFF_OPT_VERSION, DIFF_TYPE_BYTES, DIFF_TYPE_CLASSES, DIFF_TYPE_COMMAND, DIFF_TYPE_ENTRIES, DIFF_TYPE_FIELDS, DIFF_TYPE_FUNCTIONS, DIFF_TYPE_IMPORTS, DIFF_TYPE_LIBRARIES, DIFF_TYPE_LINES, DIFF_TYPE_PLOTDIFF, DIFF_TYPE_SECTIONS, DIFF_TYPE_STRINGS, DIFF_TYPE_SYMBOLS, free(), height, rz_getopt_t::ind, int, memset(), NULL, rz_diff_ctx_add_evar, rz_diff_ctx_set_def, rz_diff_ctx_set_dist, rz_diff_ctx_set_mode, rz_diff_ctx_set_opt, rz_diff_ctx_set_type, rz_diff_ctx_set_unsigned, rz_diff_error_opt, rz_diff_is_file(), rz_diff_set_def, rz_getopt_init(), rz_getopt_next(), rz_list_newf(), type, ut64(), and width.

Referenced by rz_main_rz_diff().

◆ rz_diff_resize_buffer()

static void rz_diff_resize_buffer ( DiffHexView hview)
static

Definition at line 2003 of file rz-diff.c.

2003  {
2005 
2006  ut64 size_a = ((st64)(width / 2) * (height - 2));
2007  ut64 size_b = ((st64)(width / 2) * (height - 2));
2008  st64 video_size = width;
2009  video_size *= height;
2010 
2011  hview->line = realloc(hview->line, video_size);
2012  hview->buffer_a = realloc(hview->buffer_a, size_a);
2013  hview->buffer_b = realloc(hview->buffer_b, size_b);
2014  hview->size_a = size_a;
2015  hview->size_b = size_b;
2016  hview->screen.width = width;
2017  hview->screen.height = height;
2018 
2019  rz_cons_canvas_free(hview->canvas);
2021  hview->canvas->color = true;
2022  hview->canvas->linemode = 1;
2023 
2024  rz_diff_draw_tui(hview, false);
2025 }
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144

References diff_hex_view_t::buffer_a, diff_hex_view_t::buffer_b, diff_hex_view_t::canvas, rz_cons_canvas_t::color, diff_screen_t::height, height, diff_hex_view_t::line, rz_cons_canvas_t::linemode, realloc(), rz_cons_canvas_free(), rz_cons_canvas_new(), rz_cons_get_size(), rz_diff_draw_tui(), diff_hex_view_t::screen, diff_hex_view_t::size_a, diff_hex_view_t::size_b, st64, ut64(), diff_screen_t::width, and width.

Referenced by rz_diff_hex_visual().

◆ rz_diff_sections_new()

static RzDiff* rz_diff_sections_new ( DiffFile dfile_a,
DiffFile dfile_b,
bool  compare_addr 
)
static

Definition at line 1152 of file rz-diff.c.

1152  {
1153  RzList *list_a = NULL;
1154  RzList *list_b = NULL;
1155 
1156  list_a = rz_diff_file_get(dfile_a, sections);
1157  if (!list_a) {
1158  rz_diff_error_ret(NULL, "cannot get sections from '%s'\n", dfile_a->dio->filename);
1159  }
1160 
1161  list_b = rz_diff_file_get(dfile_b, sections);
1162  if (!list_b) {
1163  rz_diff_error_ret(NULL, "cannot get sections from '%s'\n", dfile_b->dio->filename);
1164  }
1165 
1168 
1169  RzDiffMethods methods = {
1171  .elem_hash = (RzDiffMethodElemHash)(compare_addr ? section_hash_addr : section_hash),
1173  .stringify = (RzDiffMethodStringify)(compare_addr ? section_stringify_addr : section_stringify),
1174  .ignore = NULL,
1175  };
1176 
1177  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
1178 }
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
static ut32 section_hash(const RzBinSection *elem)
Definition: rz-diff.c:1122
static int section_compare(const RzBinSection *a, const RzBinSection *b)
Definition: rz-diff.c:1130
static void section_stringify(const RzBinSection *elem, RzStrBuf *sb)
Definition: rz-diff.c:1140
static int section_compare_addr(const RzBinSection *a, const RzBinSection *b)
Definition: rz-diff.c:1083
static ut32 section_hash_addr(const RzBinSection *elem)
Definition: rz-diff.c:1067
static void section_stringify_addr(const RzBinSection *elem, RzStrBuf *sb)
Definition: rz-diff.c:1109

References compare(), diff_file_t::dio, rz_diff_methods_t::elem_at, diff_io_t::filename, NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), rz_list_sort(), section_compare(), section_compare_addr(), section_hash(), section_hash_addr(), section_stringify(), section_stringify_addr(), and sections().

Referenced by rz_diff_unified_files().

◆ rz_diff_show_help()

static void rz_diff_show_help ( bool  usage_only)
static

Definition at line 195 of file rz-diff.c.

195  {
196  printf("Usage: rz-diff [options] <file0> <file1>\n");
197  if (usage_only) {
198  return;
199  }
200  printf(
201  " -a [arch] specify architecture plugin to use (x86, arm, ..)\n"
202  " -b [bits] specify register size for arch (16 (thumb), 32, 64, ..)\n"
203  " -d [algo] compute edit distance based on the choosen algorithm:\n"
204  " myers | Eugene W. Myers' O(ND) algorithm (no substitution)\n"
205  " leven | Levenshtein O(N^2) algorithm (with substitution)\n"
206  " -H hexadecimal visual mode\n"
207  " -h this help message\n"
208  " -j json output\n"
209  " -q quite output\n"
210  " -v show version information\n"
211  " -e [k=v] set an evaluable config variable\n"
212  " -A compare virtual and physical addresses\n"
213  " -B run 'aaa' when loading the bin\n"
214  " -C disable colors\n"
215  " -T show timestamp information\n"
216  " -S [WxH] sets the width and height of the terminal for visual mode\n"
217  " -0 [cmd] input for file0 when option -t 'commands' is given.\n"
218  " the same value will be set for file1, if -1 is not set.\n"
219  " -1 [cmd] input for file1 when option -t 'commands' is given.\n"
220  " -t [type] compute the difference between two files based on its type:\n"
221  " bytes | compares raw bytes in the files (only for small files)\n"
222  " lines | compares text files\n"
223  " functions | compares functions found in the files\n"
224  " classes | compares classes found in the files\n"
225  " command | compares command output returned when executed in both files\n"
226  " | requires -0 <cmd> and -1 <cmd> is optional\n"
227  " entries | compares entries found in the files\n"
228  " fields | compares fields found in the files\n"
229  " graphs | compares 2 functions and outputs in graphviz/dot format\n"
230  " | requires -0 <fcn name|offset> and -1 <fcn name|offset> is optional\n"
231  " imports | compares imports found in the files\n"
232  " libraries | compares libraries found in the files\n"
233  " sections | compares sections found in the files\n"
234  " strings | compares strings found in the files\n"
235  " symbols | compares symbols found in the files\n"
236  " palette colors can be changed by adding the following lines\n"
237  " inside the $HOME/.rizinrc file\n"
238  " ec diff.unknown blue | offset color\n"
239  " ec diff.match green | match color\n"
240  " ec diff.unmatch red | mismatch color\n"
241  "");
242 }

References printf().

Referenced by rz_main_rz_diff().

◆ rz_diff_slurp_file()

static ut8* rz_diff_slurp_file ( const char *  file,
size_t size 
)
static

Definition at line 449 of file rz-diff.c.

449  {
450  ut8 *buffer = NULL;
451  ssize_t read = 0;
452  DiffIO *dio = NULL;
453 
454  dio = rz_diff_io_open(file);
455  if (!dio) {
456  goto rz_diff_slurp_file_end;
457  }
458 
459  if (dio->filesize > MEGABYTE(5)) {
460  rz_diff_error("cannot open file '%s' because its size is above 5Mb\n", file);
461  goto rz_diff_slurp_file_end;
462  }
463 
464  buffer = malloc(dio->filesize + 1);
465  if (!buffer) {
466  rz_diff_error("cannot allocate buffer\n");
467  goto rz_diff_slurp_file_end;
468  }
469  buffer[dio->filesize] = 0;
470 
471  read = rz_io_pread_at(dio->io, 0, buffer, dio->filesize);
472  if (read != dio->filesize) {
473  free(buffer);
474  buffer = NULL;
475  rz_diff_error("cannot read buffer correctly\n");
476  goto rz_diff_slurp_file_end;
477  }
478 
479  *size = dio->filesize;
480 
481 rz_diff_slurp_file_end:
482  rz_diff_io_close(dio);
483  return buffer;
484 }
struct buffer buffer
#define MEGABYTE(x)
Definition: rz-diff.c:11
Definition: buffer.h:15

References diff_io_t::filesize, free(), diff_io_t::io, malloc(), MEGABYTE, NULL, read(), rz_diff_error, rz_diff_io_close(), rz_diff_io_open(), and rz_io_pread_at().

Referenced by rz_diff_calculate_distance(), and rz_diff_unified_files().

◆ rz_diff_strings_new()

static RzDiff* rz_diff_strings_new ( DiffFile dfile_a,
DiffFile dfile_b,
bool  compare_addr 
)
static

Definition at line 846 of file rz-diff.c.

846  {
847  RzList *list_a = NULL;
848  RzList *list_b = NULL;
849 
850  list_a = (RzList *)rz_bin_object_get_strings(dfile_a->file->o);
851  if (!list_a) {
852  rz_diff_error_ret(NULL, "cannot get strings from '%s'\n", dfile_a->dio->filename);
853  }
854 
855  list_b = (RzList *)rz_bin_object_get_strings(dfile_b->file->o);
856  if (!list_b) {
857  rz_diff_error_ret(NULL, "cannot get strings from '%s'\n", dfile_b->dio->filename);
858  }
859 
862 
863  RzDiffMethods methods = {
865  .elem_hash = (RzDiffMethodElemHash)(compare_addr ? string_hash_addr : string_hash),
867  .stringify = (RzDiffMethodStringify)(compare_addr ? string_stringify_addr : string_stringify),
868  .ignore = NULL,
869  };
870 
871  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
872 }
RZ_API const RzList * rz_bin_object_get_strings(RZ_NONNULL RzBinObject *obj)
Get list of RzBinString representing the strings identified in the binary object.
Definition: bobj.c:798
static ut32 string_hash_addr(const RzBinString *elem)
Definition: rz-diff.c:801
static int string_compare_addr(const RzBinString *a, const RzBinString *b)
Definition: rz-diff.c:810
static ut32 string_hash(const RzBinString *elem)
Definition: rz-diff.c:828
static int string_compare(const RzBinString *a, const RzBinString *b)
Definition: rz-diff.c:832
static void string_stringify_addr(const RzBinString *elem, RzStrBuf *sb)
Definition: rz-diff.c:824
static void string_stringify(const RzBinString *elem, RzStrBuf *sb)
Definition: rz-diff.c:842
RzBinFile * file
Definition: rz-diff.c:96

References compare(), diff_file_t::dio, rz_diff_methods_t::elem_at, diff_file_t::file, diff_io_t::filename, NULL, rz_bin_file_t::o, rz_bin_object_get_strings(), rz_diff_error_ret, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), rz_list_sort(), string_compare(), string_compare_addr(), string_hash(), string_hash_addr(), string_stringify(), and string_stringify_addr().

Referenced by rz_diff_unified_files().

◆ rz_diff_symbols_new()

static RzDiff* rz_diff_symbols_new ( DiffFile dfile_a,
DiffFile dfile_b,
bool  compare_addr 
)
static

Definition at line 771 of file rz-diff.c.

771  {
772  RzList *list_a = NULL;
773  RzList *list_b = NULL;
774 
775  list_a = rz_diff_file_get(dfile_a, symbols);
776  if (!list_a) {
777  rz_diff_error_ret(NULL, "cannot get symbols from '%s'\n", dfile_a->dio->filename);
778  }
779 
780  list_b = rz_diff_file_get(dfile_b, symbols);
781  if (!list_b) {
782  rz_diff_error_ret(NULL, "cannot get symbols from '%s'\n", dfile_b->dio->filename);
783  }
784 
787 
788  RzDiffMethods methods = {
790  .elem_hash = (RzDiffMethodElemHash)(compare_addr ? symbol_hash_addr : symbol_hash),
792  .stringify = (RzDiffMethodStringify)(compare_addr ? symbol_stringify_addr : symbol_stringify),
793  .ignore = NULL,
794  };
795 
796  return rz_diff_generic_new(list_a, rz_list_length(list_a), list_b, rz_list_length(list_b), &methods);
797 }
RzList * symbols(RzBinFile *bf)
Definition: bin_ne.c:102
static ut32 symbol_hash_addr(const RzBinSymbol *elem)
Definition: rz-diff.c:728
static void symbol_stringify_addr(const RzBinSymbol *elem, RzStrBuf *sb)
Definition: rz-diff.c:753
static int symbol_compare_addr(const RzBinSymbol *a, const RzBinSymbol *b)
Definition: rz-diff.c:740
static int symbol_compare(const RzBinSymbol *a, const RzBinSymbol *b)
Definition: rz-diff.c:761
static ut32 symbol_hash(const RzBinSymbol *elem)
Definition: rz-diff.c:757
static void symbol_stringify(const RzBinSymbol *elem, RzStrBuf *sb)
Definition: rz-diff.c:767

References compare(), diff_file_t::dio, rz_diff_methods_t::elem_at, diff_io_t::filename, NULL, rz_diff_error_ret, rz_diff_file_get, rz_diff_generic_new(), rz_diff_list_elem_at(), rz_list_length(), rz_list_sort(), symbol_compare(), symbol_compare_addr(), symbol_hash(), symbol_hash_addr(), symbol_stringify(), symbol_stringify_addr(), and symbols().

Referenced by rz_diff_unified_files().

◆ rz_diff_unified_files()

static bool rz_diff_unified_files ( DiffContext ctx)
static

Definition at line 1297 of file rz-diff.c.

1297  {
1298  size_t a_size = 0;
1299  size_t b_size = 0;
1300  ut8 *a_buffer = NULL;
1301  ut8 *b_buffer = NULL;
1302  DiffFile dfile_a = { 0 };
1303  DiffFile dfile_b = { 0 };
1304  RzDiff *diff = NULL;
1305  bool result = false;
1306 
1307  if (ctx->type == DIFF_TYPE_BYTES ||
1308  ctx->type == DIFF_TYPE_LINES) {
1309  if (!(a_buffer = rz_diff_slurp_file(ctx->file_a, &a_size))) {
1310  goto rz_diff_unified_files_bad;
1311  }
1312 
1313  if (!(b_buffer = rz_diff_slurp_file(ctx->file_b, &b_size))) {
1314  goto rz_diff_unified_files_bad;
1315  }
1316  } else if (ctx->type != DIFF_TYPE_FUNCTIONS && ctx->type != DIFF_TYPE_COMMAND) {
1317  if (!rz_diff_file_open(&dfile_a, ctx->file_a)) {
1318  goto rz_diff_unified_files_bad;
1319  }
1320  if (!rz_diff_file_open(&dfile_b, ctx->file_b)) {
1321  goto rz_diff_unified_files_bad;
1322  }
1323  }
1324 
1325  switch (ctx->type) {
1326  case DIFF_TYPE_BYTES:
1327  diff = rz_diff_bytes_new(a_buffer, a_size, b_buffer, b_size, NULL);
1328  break;
1329  case DIFF_TYPE_CLASSES:
1330  diff = rz_diff_classes_new(&dfile_a, &dfile_b, ctx->compare_addresses);
1331  break;
1332  case DIFF_TYPE_COMMAND:
1333  diff = rz_diff_command_new(ctx);
1334  break;
1335  case DIFF_TYPE_ENTRIES:
1336  diff = rz_diff_entries_new(&dfile_a, &dfile_b);
1337  break;
1338  case DIFF_TYPE_FIELDS:
1339  diff = rz_diff_fields_new(&dfile_a, &dfile_b, ctx->compare_addresses);
1340  break;
1341  case DIFF_TYPE_IMPORTS:
1342  diff = rz_diff_imports_new(&dfile_a, &dfile_b);
1343  break;
1344  case DIFF_TYPE_LIBRARIES:
1345  diff = rz_diff_libraries_new(&dfile_a, &dfile_b);
1346  break;
1347  case DIFF_TYPE_LINES:
1348  diff = rz_diff_lines_new((const char *)a_buffer, (const char *)b_buffer, NULL);
1349  break;
1350  case DIFF_TYPE_SECTIONS:
1351  diff = rz_diff_sections_new(&dfile_a, &dfile_b, ctx->compare_addresses);
1352  break;
1353  case DIFF_TYPE_STRINGS:
1354  diff = rz_diff_strings_new(&dfile_a, &dfile_b, ctx->compare_addresses);
1355  break;
1356  case DIFF_TYPE_SYMBOLS:
1357  diff = rz_diff_symbols_new(&dfile_a, &dfile_b, ctx->compare_addresses);
1358  break;
1359  default:
1360  rz_diff_error("unknown type\n");
1361  goto rz_diff_unified_files_bad;
1362  }
1363 
1364  if (!diff) {
1365  goto rz_diff_unified_files_bad;
1366  }
1367 
1368  if (ctx->mode == DIFF_MODE_JSON) {
1369  PJ *pj = rz_diff_unified_json(diff, ctx->file_a, ctx->file_b, ctx->show_time);
1370  if (!pj) {
1371  goto rz_diff_unified_files_bad;
1372  }
1373  printf("%s\n", pj_string(pj));
1374  pj_free(pj);
1375  } else {
1376  // DIFF_MODE_STANDARD & DIFF_MODE_QUIET
1377  char *result = rz_diff_unified_text(diff, ctx->file_a, ctx->file_b, ctx->show_time, ctx->colors);
1378  if (!result) {
1379  goto rz_diff_unified_files_bad;
1380  }
1381  puts(result);
1382  free(result);
1383  }
1384 
1385  result = true;
1386 
1387 rz_diff_unified_files_bad:
1388  rz_diff_free(diff);
1389  rz_diff_file_close(&dfile_a);
1390  rz_diff_file_close(&dfile_b);
1391  free(a_buffer);
1392  free(b_buffer);
1393  return result;
1394 }
RZ_API RZ_OWN RzDiff * rz_diff_bytes_new(RZ_BORROW const ut8 *a, ut32 a_size, RZ_BORROW const ut8 *b, ut32 b_size, RZ_NULLABLE RzDiffIgnoreByte ignore)
Returns the structure needed to diff buffers of ut8.
Definition: diff.c:188
RZ_API void rz_diff_free(RZ_NULLABLE RzDiff *diff)
frees the diff structure
Definition: diff.c:295
static RzDiff * rz_diff_symbols_new(DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
Definition: rz-diff.c:771
static RzDiff * rz_diff_libraries_new(DiffFile *dfile_a, DiffFile *dfile_b)
Definition: rz-diff.c:1037
static RzDiff * rz_diff_entries_new(DiffFile *dfile_a, DiffFile *dfile_b)
Definition: rz-diff.c:993
static bool rz_diff_file_open(DiffFile *dfile, const char *filename)
Definition: rz-diff.c:617
static RzDiff * rz_diff_sections_new(DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
Definition: rz-diff.c:1152
static RzDiff * rz_diff_command_new(DiffContext *ctx)
Definition: rz-diff.c:1274
static void rz_diff_file_close(DiffFile *file)
Definition: rz-diff.c:662
static RzDiff * rz_diff_fields_new(DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
Definition: rz-diff.c:1229
static RzDiff * rz_diff_imports_new(DiffFile *dfile_a, DiffFile *dfile_b)
Definition: rz-diff.c:698
static RzDiff * rz_diff_strings_new(DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
Definition: rz-diff.c:846
static RzDiff * rz_diff_classes_new(DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr)
Definition: rz-diff.c:912
RZ_API RZ_OWN char * rz_diff_unified_text(RZ_NONNULL RzDiff *diff, RZ_NULLABLE const char *from, RZ_NULLABLE const char *to, bool show_time, bool color)
Produces a diff output with A and B inputs presented immediately adjacent to each other.
Definition: unified_diff.c:333
RZ_API RZ_OWN PJ * rz_diff_unified_json(RZ_NONNULL RzDiff *diff, RZ_NULLABLE const char *from, RZ_NULLABLE const char *to, bool show_time)
Produces a diff output to convert A in B in a JSON format.
Definition: unified_diff.c:409

References DIFF_MODE_JSON, DIFF_TYPE_BYTES, DIFF_TYPE_CLASSES, DIFF_TYPE_COMMAND, DIFF_TYPE_ENTRIES, DIFF_TYPE_FIELDS, DIFF_TYPE_FUNCTIONS, DIFF_TYPE_IMPORTS, DIFF_TYPE_LIBRARIES, DIFF_TYPE_LINES, DIFF_TYPE_SECTIONS, DIFF_TYPE_STRINGS, DIFF_TYPE_SYMBOLS, free(), NULL, pj_free(), pj_string(), printf(), rz_diff_bytes_new(), rz_diff_classes_new(), rz_diff_command_new(), rz_diff_entries_new(), rz_diff_error, rz_diff_fields_new(), rz_diff_file_close(), rz_diff_file_open(), rz_diff_free(), rz_diff_imports_new(), rz_diff_libraries_new(), rz_diff_lines_new(), rz_diff_sections_new(), rz_diff_slurp_file(), rz_diff_strings_new(), rz_diff_symbols_new(), rz_diff_unified_json(), and rz_diff_unified_text().

Referenced by rz_main_rz_diff().

◆ rz_main_rz_diff()

RZ_API int rz_main_rz_diff ( int  argc,
const char **  argv 
)

Definition at line 2254 of file rz-diff.c.

2254  {
2255  bool success = false;
2256  DiffContext ctx;
2257  rz_diff_parse_arguments(argc, argv, &ctx);
2258 
2259  switch (ctx.option) {
2260  case DIFF_OPT_DISTANCE:
2261  success = rz_diff_calculate_distance(&ctx);
2262  break;
2263  case DIFF_OPT_UNIFIED:
2264  success = rz_diff_unified_files(&ctx);
2265  break;
2266  case DIFF_OPT_GRAPH:
2267  success = rz_diff_graphs_files(&ctx);
2268  break;
2269  case DIFF_OPT_HEX_VISUAL:
2270  success = rz_diff_hex_visual(&ctx);
2271  break;
2272  case DIFF_OPT_VERSION:
2273  rz_main_version_print("rz-diff");
2274  success = true;
2275  break;
2276  case DIFF_OPT_USAGE:
2277  rz_diff_show_help(true);
2278  break;
2279  case DIFF_OPT_ERROR:
2280  break;
2281  case DIFF_OPT_HELP:
2282  success = true;
2283  // fallthrough
2284  default:
2285  rz_diff_show_help(false);
2286  break;
2287  }
2288 
2289  rz_list_free(ctx.evars);
2290  return success ? 0 : 1;
2291 }
static void rz_diff_show_help(bool usage_only)
Definition: rz-diff.c:195
static bool rz_diff_calculate_distance(DiffContext *ctx)
Definition: rz-diff.c:486
static bool rz_diff_hex_visual(DiffContext *ctx)
Definition: rz-diff.c:2027
static bool rz_diff_graphs_files(DiffContext *ctx)
Definition: rz-diff.c:1413
static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ctx)
Definition: rz-diff.c:254
static bool rz_diff_unified_files(DiffContext *ctx)
Definition: rz-diff.c:1297
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API int rz_main_version_print(const char *program)
Definition: main.c:49

References argv, DIFF_OPT_DISTANCE, DIFF_OPT_ERROR, DIFF_OPT_GRAPH, DIFF_OPT_HELP, DIFF_OPT_HEX_VISUAL, DIFF_OPT_UNIFIED, DIFF_OPT_USAGE, DIFF_OPT_VERSION, rz_diff_calculate_distance(), rz_diff_graphs_files(), rz_diff_hex_visual(), rz_diff_parse_arguments(), rz_diff_show_help(), rz_diff_unified_files(), rz_list_free(), and rz_main_version_print().

Referenced by MAIN_NAME(), and rz_main_rizin().

◆ section_compare()

static int section_compare ( const RzBinSection a,
const RzBinSection b 
)
static

Definition at line 1130 of file rz-diff.c.

1130  {
1131  st64 ret;
1132  IF_STRCMP_S(ret, a->name, b->name);
1133  ret = ((st64)b->perm) - ((st64)a->perm);
1134  if (ret) {
1135  return ret;
1136  }
1137  return ((st64)b->align) - ((st64)a->align);
1138 }

References a, b, IF_STRCMP_S, and st64.

Referenced by rz_diff_sections_new().

◆ section_compare_addr()

static int section_compare_addr ( const RzBinSection a,
const RzBinSection b 
)
static

Definition at line 1083 of file rz-diff.c.

1083  {
1084  st64 ret;
1085  IF_STRCMP_S(ret, a->name, b->name);
1086  ret = ((st64)b->size) - ((st64)a->size);
1087  if (ret) {
1088  return ret;
1089  }
1090  ret = ((st64)b->vsize) - ((st64)a->vsize);
1091  if (ret) {
1092  return ret;
1093  }
1094  ret = ((st64)b->paddr) - ((st64)a->paddr);
1095  if (ret) {
1096  return ret;
1097  }
1098  ret = ((st64)b->vaddr) - ((st64)a->vaddr);
1099  if (ret) {
1100  return ret;
1101  }
1102  ret = ((st64)b->perm) - ((st64)a->perm);
1103  if (ret) {
1104  return ret;
1105  }
1106  return ((st64)b->align) - ((st64)a->align);
1107 }

References a, b, IF_STRCMP_S, and st64.

Referenced by rz_diff_sections_new().

◆ section_hash()

static ut32 section_hash ( const RzBinSection elem)
static

Definition at line 1122 of file rz-diff.c.

1122  {
1123  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
1124  hash ^= elem->perm;
1125  hash ^= (ut32)(elem->align >> 32);
1126  hash ^= (ut32)elem->align;
1127  return hash;
1128 }
char * name
Definition: rz_bin.h:619

References rz_bin_section_t::align, rz_bin_section_t::name, rz_bin_section_t::perm, and rz_diff_hash_data().

Referenced by rz_diff_sections_new().

◆ section_hash_addr()

static ut32 section_hash_addr ( const RzBinSection elem)
static

Definition at line 1067 of file rz-diff.c.

1067  {
1068  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
1069  hash ^= elem->perm;
1070  hash ^= (ut32)(elem->align >> 32);
1071  hash ^= (ut32)elem->align;
1072  hash ^= (ut32)(elem->vsize >> 32);
1073  hash ^= (ut32)elem->vsize;
1074  hash ^= (ut32)(elem->size >> 32);
1075  hash ^= (ut32)elem->size;
1076  hash ^= (ut32)(elem->vaddr >> 32);
1077  hash ^= (ut32)elem->vaddr;
1078  hash ^= (ut32)(elem->paddr >> 32);
1079  hash ^= (ut32)elem->paddr;
1080  return hash;
1081 }

References rz_bin_section_t::align, rz_bin_section_t::name, rz_bin_section_t::paddr, rz_bin_section_t::perm, rz_diff_hash_data(), rz_bin_section_t::size, rz_bin_section_t::vaddr, and rz_bin_section_t::vsize.

Referenced by rz_diff_sections_new().

◆ section_stringify()

static void section_stringify ( const RzBinSection elem,
RzStrBuf sb 
)
static

Definition at line 1140 of file rz-diff.c.

1140  {
1141  char perm[5];
1142 
1143  perm[0] = elem->perm & RZ_PERM_SHAR ? 's' : '-';
1144  perm[1] = elem->perm & RZ_PERM_R ? 'r' : '-';
1145  perm[2] = elem->perm & RZ_PERM_W ? 'w' : '-';
1146  perm[3] = elem->perm & RZ_PERM_X ? 'x' : '-';
1147  perm[4] = 0;
1148 
1149  rz_strbuf_setf(sb, "align: 0x%08" PFMT64x " %s %s\n", elem->align, perm, elem->name);
1150 }
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_PERM_SHAR
Definition: rz_types.h:100

References rz_bin_section_t::align, rz_bin_section_t::name, rz_bin_section_t::perm, PFMT64x, RZ_PERM_R, RZ_PERM_SHAR, RZ_PERM_W, RZ_PERM_X, rz_strbuf_setf(), and sb.

Referenced by rz_diff_sections_new().

◆ section_stringify_addr()

static void section_stringify_addr ( const RzBinSection elem,
RzStrBuf sb 
)
static

Definition at line 1109 of file rz-diff.c.

1109  {
1110  char perm[5];
1111 
1112  perm[0] = elem->perm & RZ_PERM_SHAR ? 's' : '-';
1113  perm[1] = elem->perm & RZ_PERM_R ? 'r' : '-';
1114  perm[2] = elem->perm & RZ_PERM_W ? 'w' : '-';
1115  perm[3] = elem->perm & RZ_PERM_X ? 'x' : '-';
1116  perm[4] = 0;
1117 
1118  rz_strbuf_setf(sb, "virt: 0x%016" PFMT64x ":0x%04" PFMT64x " phys: 0x%016" PFMT64x ":0x%04" PFMT64x " align: 0x%08" PFMT64x " %s %s\n",
1119  elem->vaddr, elem->vsize, elem->paddr, elem->size, elem->align, perm, elem->name);
1120 }

References rz_bin_section_t::align, rz_bin_section_t::name, rz_bin_section_t::paddr, rz_bin_section_t::perm, PFMT64x, RZ_PERM_R, RZ_PERM_SHAR, RZ_PERM_W, RZ_PERM_X, rz_strbuf_setf(), sb, rz_bin_section_t::size, rz_bin_section_t::vaddr, and rz_bin_section_t::vsize.

Referenced by rz_diff_sections_new().

◆ seek_min_shift()

static int seek_min_shift ( DiffHexView hview)
inlinestatic

Definition at line 1602 of file rz-diff.c.

1602  {
1603  int width = hview->screen.width;
1604  if (width >= (DIFF_HEX_32 * 2)) {
1605  return 5;
1606  } else if (width >= (DIFF_HEX_16 * 2)) {
1607  return 4;
1608  }
1609  return 3;
1610 }

References DIFF_HEX_16, DIFF_HEX_32, diff_hex_view_t::screen, diff_screen_t::width, and width.

Referenced by rz_diff_draw_tui().

◆ seek_min_value()

static int seek_min_value ( DiffHexView hview)
inlinestatic

Definition at line 1612 of file rz-diff.c.

1612  {
1613  int width = hview->screen.width;
1614  if (width >= (DIFF_HEX_32 * 2)) {
1615  return 32;
1616  } else if (width >= (DIFF_HEX_16 * 2)) {
1617  return 16;
1618  }
1619  return 8;
1620 }

References DIFF_HEX_16, DIFF_HEX_32, diff_hex_view_t::screen, diff_screen_t::width, and width.

Referenced by rz_diff_hex_visual().

◆ string_compare()

static int string_compare ( const RzBinString a,
const RzBinString b 
)
static

Definition at line 832 of file rz-diff.c.

832  {
833  st64 ret;
834  ret = ((st64)b->size) - ((st64)a->size);
835  if (ret) {
836  return ret;
837  }
838  IF_STRCMP_S(ret, a->string, b->string);
839  return 0;
840 }

References a, b, IF_STRCMP_S, and st64.

Referenced by rz_diff_strings_new().

◆ string_compare_addr()

static int string_compare_addr ( const RzBinString a,
const RzBinString b 
)
static

Definition at line 810 of file rz-diff.c.

810  {
811  st64 ret;
812  ret = ((st64)b->size) - ((st64)a->size);
813  if (ret) {
814  return ret;
815  }
816  IF_STRCMP_S(ret, a->string, b->string);
817  ret = ((st64)b->paddr) - ((st64)a->paddr);
818  if (ret) {
819  return ret;
820  }
821  return ((st64)b->vaddr) - ((st64)a->vaddr);
822 }

References a, b, IF_STRCMP_S, and st64.

Referenced by rz_diff_strings_new().

◆ string_hash()

static ut32 string_hash ( const RzBinString elem)
static

Definition at line 828 of file rz-diff.c.

828  {
829  return rz_diff_hash_data((const ut8 *)elem->string, elem->size);
830 }
char * string
Definition: rz_bin.h:752

References rz_diff_hash_data(), rz_bin_string_t::size, and rz_bin_string_t::string.

Referenced by rz_diff_strings_new().

◆ string_hash_addr()

static ut32 string_hash_addr ( const RzBinString elem)
static

Definition at line 801 of file rz-diff.c.

801  {
802  ut32 hash = rz_diff_hash_data((const ut8 *)elem->string, elem->size);
803  hash ^= (ut32)(elem->vaddr >> 32);
804  hash ^= (ut32)elem->vaddr;
805  hash ^= (ut32)(elem->paddr >> 32);
806  hash ^= (ut32)elem->paddr;
807  return hash;
808 }

References rz_bin_string_t::paddr, rz_diff_hash_data(), rz_bin_string_t::size, rz_bin_string_t::string, and rz_bin_string_t::vaddr.

Referenced by rz_diff_strings_new().

◆ string_stringify()

static void string_stringify ( const RzBinString elem,
RzStrBuf sb 
)
static

Definition at line 842 of file rz-diff.c.

842  {
843  rz_strbuf_setf(sb, "%s\n", elem->string);
844 }

References rz_strbuf_setf(), sb, and rz_bin_string_t::string.

Referenced by rz_diff_strings_new().

◆ string_stringify_addr()

static void string_stringify_addr ( const RzBinString elem,
RzStrBuf sb 
)
static

Definition at line 824 of file rz-diff.c.

824  {
825  rz_strbuf_setf(sb, "virt: 0x%016" PFMT64x " phys: 0x%016" PFMT64x " %s\n", elem->vaddr, elem->paddr, elem->string);
826 }

References rz_bin_string_t::paddr, PFMT64x, rz_strbuf_setf(), sb, rz_bin_string_t::string, and rz_bin_string_t::vaddr.

Referenced by rz_diff_strings_new().

◆ symbol_compare()

static int symbol_compare ( const RzBinSymbol a,
const RzBinSymbol b 
)
static

Definition at line 761 of file rz-diff.c.

761  {
762  int ret;
763  IF_STRCMP_S(ret, a->name, b->name);
764  return 0;
765 }

References a, b, and IF_STRCMP_S.

Referenced by rz_diff_symbols_new().

◆ symbol_compare_addr()

static int symbol_compare_addr ( const RzBinSymbol a,
const RzBinSymbol b 
)
static

Definition at line 740 of file rz-diff.c.

740  {
741  st64 ret;
742  IF_STRCMP_S(ret, a->classname, b->classname);
743  IF_STRCMP_S(ret, a->libname, b->libname);
744  IF_STRCMP_S(ret, a->dname, b->dname);
745  IF_STRCMP_S(ret, a->name, b->name);
746  ret = ((st64)b->paddr) - ((st64)a->paddr);
747  if (ret) {
748  return ret;
749  }
750  return ((st64)b->vaddr) - ((st64)a->vaddr);
751 }

References a, b, IF_STRCMP_S, and st64.

Referenced by rz_diff_symbols_new().

◆ symbol_hash()

static ut32 symbol_hash ( const RzBinSymbol elem)
static

Definition at line 757 of file rz-diff.c.

757  {
758  return rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
759 }
char * name
Definition: rz_bin.h:675

References rz_bin_symbol_t::name, and rz_diff_hash_data().

Referenced by rz_diff_symbols_new().

◆ symbol_hash_addr()

static ut32 symbol_hash_addr ( const RzBinSymbol elem)
static

Definition at line 728 of file rz-diff.c.

728  {
729  ut32 hash = rz_diff_hash_data((const ut8 *)elem->name, strlen(elem->name));
730  hash ^= rz_diff_hash_data((const ut8 *)elem->dname, strlen(elem->dname));
731  hash ^= rz_diff_hash_data((const ut8 *)elem->libname, strlen(elem->libname));
732  hash ^= rz_diff_hash_data((const ut8 *)elem->classname, strlen(elem->classname));
733  hash ^= (ut32)(elem->vaddr >> 32);
734  hash ^= (ut32)elem->vaddr;
735  hash ^= (ut32)(elem->paddr >> 32);
736  hash ^= (ut32)elem->paddr;
737  return hash;
738 }
char * classname
Definition: rz_bin.h:678
char * dname
Definition: rz_bin.h:676
char * libname
Definition: rz_bin.h:677

References rz_bin_symbol_t::classname, rz_bin_symbol_t::dname, rz_bin_symbol_t::libname, rz_bin_symbol_t::name, rz_bin_symbol_t::paddr, rz_diff_hash_data(), and rz_bin_symbol_t::vaddr.

Referenced by rz_diff_symbols_new().

◆ symbol_stringify()

static void symbol_stringify ( const RzBinSymbol elem,
RzStrBuf sb 
)
static

Definition at line 767 of file rz-diff.c.

767  {
768  rz_strbuf_setf(sb, "%s %s %s\n", elem->libname, elem->classname, elem->name);
769 }

References rz_bin_symbol_t::classname, rz_bin_symbol_t::libname, rz_bin_symbol_t::name, rz_strbuf_setf(), and sb.

Referenced by rz_diff_symbols_new().

◆ symbol_stringify_addr()

static void symbol_stringify_addr ( const RzBinSymbol elem,
RzStrBuf sb 
)
static

Definition at line 753 of file rz-diff.c.

753  {
754  rz_strbuf_setf(sb, "virt: 0x%016" PFMT64x " phys: 0x%016" PFMT64x " %s %s %s\n", elem->vaddr, elem->paddr, elem->libname, elem->classname, elem->name);
755 }

References rz_bin_symbol_t::classname, rz_bin_symbol_t::libname, rz_bin_symbol_t::name, rz_bin_symbol_t::paddr, PFMT64x, rz_strbuf_setf(), sb, and rz_bin_symbol_t::vaddr.

Referenced by rz_diff_symbols_new().

◆ visual_prompt()

static char* visual_prompt ( DiffHexView hview,
const char *  prompt 
)
static

Definition at line 1840 of file rz-diff.c.

1840  {
1841  char buf[1024];
1842  rz_cons_gotoxy(0, hview->screen.height);
1843  rz_cons_clear_line(0);
1844  rz_cons_printf("%s%s ", hview->colors.reset, prompt);
1845  rz_line_set_prompt(":> ");
1846  rz_cons_flush();
1847  rz_cons_fgets(buf, sizeof(buf), 0, NULL);
1848  if (*buf) {
1849  return strdup(buf);
1850  }
1851  return NULL;
1852 }
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_gotoxy(int x, int y)
Definition: cons.c:724
RZ_API int rz_cons_fgets(char *buf, int len, int argc, const char **argv)
Definition: input.c:339
voidpf void * buf
Definition: ioapi.h:138
RZ_API void rz_line_set_prompt(const char *prompt)
Definition: line.c:56
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static char * prompt(const char *str, const char *txt)
Definition: vmenus.c:30

References diff_hex_view_t::colors, diff_screen_t::height, NULL, prompt(), diff_colors_t::reset, rz_cons_clear_line(), rz_cons_fgets(), rz_cons_flush(), rz_cons_gotoxy(), rz_cons_printf(), rz_line_set_prompt(), diff_hex_view_t::screen, and strdup().

Referenced by prompt_offset_and_seek(), and prompt_offset_and_seek_file().