Rizin
unix-like reverse engineering framework and cli tools
reflines.c File Reference
#include <rz_core.h>
#include <rz_util.h>
#include <rz_cons.h>

Go to the source code of this file.

Classes

struct  refline_end
 

Macros

#define mid_down_refline(a, r)   ((r)->from > (r)->to && (a) < (r)->from && (a) > (r)->to)
 
#define mid_up_refline(a, r)   ((r)->from < (r)->to && (a) > (r)->from && (a) < (r)->to)
 
#define mid_refline(a, r)   (mid_down_refline(a, r) || mid_up_refline(a, r))
 
#define in_refline(a, r)   (mid_refline(a, r) || (a) == (r)->from || (a) == (r)->to)
 

Typedefs

typedef struct refline_end ReflineEnd
 

Functions

static int cmp_asc (const struct refline_end *a, const struct refline_end *b)
 
static int cmp_by_ref_lvl (const RzAnalysisRefline *a, const RzAnalysisRefline *b)
 
static ReflineEndrefline_end_new (ut64 val, bool is_from, RzAnalysisRefline *ref)
 
static bool add_refline (RzList *list, RzList *sten, ut64 addr, ut64 to, int *idx)
 
RZ_API void rz_analysis_reflines_free (RzAnalysisRefline *rl)
 
RZ_API RzListrz_analysis_reflines_get (RzAnalysis *analysis, ut64 addr, const ut8 *buf, ut64 len, int nlines, int linesout, int linescall)
 
RZ_API int rz_analysis_reflines_middle (RzAnalysis *a, RzList *list, ut64 addr, int len)
 
static const char * get_corner_char (RzAnalysisRefline *ref, ut64 addr, bool is_middle_before)
 
static void add_spaces (RzBuffer *b, int level, int pos, bool wide)
 
static void fill_level (RzBuffer *b, int pos, char ch, RzAnalysisRefline *r, bool wide)
 
static bool refline_kept (RzAnalysisRefline *ref, bool middle_after, ut64 addr)
 
RZ_API RzAnalysisRefStrrz_analysis_reflines_str (void *_core, ut64 addr, int opts)
 
RZ_API void rz_analysis_reflines_str_free (RzAnalysisRefStr *refstr)
 

Macro Definition Documentation

◆ in_refline

#define in_refline (   a,
  r 
)    (mid_refline(a, r) || (a) == (r)->from || (a) == (r)->to)

Definition at line 12 of file reflines.c.

◆ mid_down_refline

#define mid_down_refline (   a,
  r 
)    ((r)->from > (r)->to && (a) < (r)->from && (a) > (r)->to)

Definition at line 9 of file reflines.c.

◆ mid_refline

#define mid_refline (   a,
  r 
)    (mid_down_refline(a, r) || mid_up_refline(a, r))

Definition at line 11 of file reflines.c.

◆ mid_up_refline

#define mid_up_refline (   a,
  r 
)    ((r)->from < (r)->to && (a) > (r)->from && (a) < (r)->to)

Definition at line 10 of file reflines.c.

Typedef Documentation

◆ ReflineEnd

typedef struct refline_end ReflineEnd

Function Documentation

◆ add_refline()

static bool add_refline ( RzList list,
RzList sten,
ut64  addr,
ut64  to,
int idx 
)
static

Definition at line 39 of file reflines.c.

39  {
40  ReflineEnd *re1, *re2;
42  if (!item) {
43  return false;
44  }
45  item->from = addr;
46  item->to = to;
47  item->index = *idx;
48  item->level = -1;
49  item->direction = (to > addr) ? 1 : -1;
50  *idx += 1;
51  rz_list_append(list, item);
52 
53  re1 = refline_end_new(item->from, true, item);
54  if (!re1) {
55  free(item);
56  return false;
57  }
59 
60  re2 = refline_end_new(item->to, false, item);
61  if (!re2) {
62  free(re1);
63  free(item);
64  return false;
65  }
67  return true;
68 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static void list(RzEgg *egg)
Definition: rz-gg.c:52
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 RZ_BORROW RzListIter * rz_list_add_sorted(RZ_NONNULL RzList *list, void *data, RZ_NONNULL RzListComparator cmp)
Adds an element to a sorted list via the RzListComparator.
Definition: list.c:518
int idx
Definition: setup.py:197
static ReflineEnd * refline_end_new(ut64 val, bool is_from, RzAnalysisRefline *ref)
Definition: reflines.c:28
static int cmp_asc(const struct refline_end *a, const struct refline_end *b)
Definition: reflines.c:20
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
#define RZ_NEW0(x)
Definition: rz_types.h:284
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static int addr
Definition: z80asm.c:58

References addr, cmp_asc(), rz_analysis_refline_t::direction, free(), rz_analysis_refline_t::from, setup::idx, rz_analysis_refline_t::index, rz_analysis_refline_t::level, list(), refline_end_new(), rz_list_add_sorted(), rz_list_append(), RZ_NEW0, rz_analysis_refline_t::to, and to.

Referenced by rz_analysis_reflines_get().

◆ add_spaces()

static void add_spaces ( RzBuffer b,
int  level,
int  pos,
bool  wide 
)
static

Definition at line 298 of file reflines.c.

298  {
299  if (pos != -1) {
300  if (wide) {
301  pos *= 2;
302  level *= 2;
303  }
304  if (pos > level + 1) {
305  const char *pd = rz_str_pad(' ', pos - level - 1);
306  rz_buf_append_string(b, pd);
307  }
308  }
309 }
RZ_API st64 rz_buf_append_string(RZ_NONNULL RzBuffer *b, RZ_NONNULL const char *str)
Append a string to the buffer.
Definition: buf.c:962
RZ_API const char * rz_str_pad(const char ch, int len)
Definition: str.c:3236
#define b(i)
Definition: sha256.c:42
int pos
Definition: main.c:11
static int level
Definition: vmenus.c:2424

References b, level, pos, rz_buf_append_string(), and rz_str_pad().

Referenced by rz_analysis_reflines_str().

◆ cmp_asc()

static int cmp_asc ( const struct refline_end a,
const struct refline_end b 
)
static

Definition at line 20 of file reflines.c.

20  {
21  return (a->val > b->val) - (a->val < b->val);
22 }
#define a(i)
Definition: sha256.c:41

References a, and b.

Referenced by add_refline().

◆ cmp_by_ref_lvl()

static int cmp_by_ref_lvl ( const RzAnalysisRefline a,
const RzAnalysisRefline b 
)
static

Definition at line 24 of file reflines.c.

24  {
25  return (a->level < b->level) - (a->level > b->level);
26 }

References a, and b.

Referenced by rz_analysis_reflines_str().

◆ fill_level()

static void fill_level ( RzBuffer b,
int  pos,
char  ch,
RzAnalysisRefline r,
bool  wide 
)
static

Definition at line 311 of file reflines.c.

311  {
312  int sz = r->level;
313  if (wide) {
314  sz *= 2;
315  }
316  const char *pd = rz_str_pad(ch, sz - 1);
317  if (pos == -1) {
318  rz_buf_append_string(b, pd);
319  } else {
320  int pdlen = strlen(pd);
321  if (pdlen > 0) {
322  rz_buf_write_at(b, pos, (const ut8 *)pd, pdlen);
323  }
324  }
325 }
#define r
Definition: crypto_rc6.c:12
uint8_t ut8
Definition: lh5801.h:11
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197

References b, pos, r, rz_buf_append_string(), rz_buf_write_at(), and rz_str_pad().

Referenced by rz_analysis_reflines_str().

◆ get_corner_char()

static const char* get_corner_char ( RzAnalysisRefline ref,
ut64  addr,
bool  is_middle_before 
)
static

Definition at line 279 of file reflines.c.

279  {
280  if (ref->from == ref->to) {
281  return "@";
282  }
283  if (addr == ref->to) {
284  if (is_middle_before) {
285  return (ref->from > ref->to) ? " " : "|";
286  }
287  return (ref->from > ref->to) ? "." : "`";
288  }
289  if (addr == ref->from) {
290  if (is_middle_before) {
291  return (ref->from > ref->to) ? "|" : " ";
292  }
293  return (ref->from > ref->to) ? "`" : ",";
294  }
295  return "";
296 }

References addr, rz_analysis_refline_t::from, and rz_analysis_refline_t::to.

Referenced by rz_analysis_reflines_str().

◆ refline_end_new()

static ReflineEnd* refline_end_new ( ut64  val,
bool  is_from,
RzAnalysisRefline ref 
)
static

Definition at line 28 of file reflines.c.

28  {
29  ReflineEnd *re = RZ_NEW0(struct refline_end);
30  if (!re) {
31  return NULL;
32  }
33  re->val = val;
34  re->is_from = is_from;
35  re->r = ref;
36  return re;
37 }
ut16 val
Definition: armass64_const.h:6
#define NULL
Definition: cris-opc.c:27
RzAnalysisRefline * r
Definition: reflines.c:17
bool is_from
Definition: reflines.c:16

References refline_end::is_from, NULL, refline_end::r, RZ_NEW0, refline_end::val, and val.

Referenced by add_refline().

◆ refline_kept()

static bool refline_kept ( RzAnalysisRefline ref,
bool  middle_after,
ut64  addr 
)
inlinestatic

Definition at line 327 of file reflines.c.

327  {
328  if (middle_after) {
329  if (ref->direction < 0) {
330  if (ref->from == addr) {
331  return false;
332  }
333  } else {
334  if (ref->to == addr) {
335  return false;
336  }
337  }
338  }
339  return true;
340 }

References addr, rz_analysis_refline_t::direction, rz_analysis_refline_t::from, and rz_analysis_refline_t::to.

Referenced by rz_analysis_reflines_str().

◆ rz_analysis_reflines_free()

RZ_API void rz_analysis_reflines_free ( RzAnalysisRefline rl)

Definition at line 70 of file reflines.c.

70  {
71  free(rl);
72 }

References free().

◆ rz_analysis_reflines_get()

RZ_API RzList* rz_analysis_reflines_get ( RzAnalysis analysis,
ut64  addr,
const ut8 buf,
ut64  len,
int  nlines,
int  linesout,
int  linescall 
)

Definition at line 82 of file reflines.c.

82  {
83  RzList *list, *sten;
86  struct refline_end *el;
87  const ut8 *ptr = buf;
88  const ut8 *end = buf + len;
89  ut8 *free_levels;
90  int sz = 0, count = 0;
91  ut64 opc = addr;
92 
93  memset(&op, 0, sizeof(op));
94  /*
95  * 1) find all reflines
96  * 2) sort "from"s and "to"s in a list
97  * 3) traverse the list to find the minimum available level for each refline
98  * * create a sorted list with available levels.
99  * * when we encounter a previously unseen "from" or "to" of a
100  * refline, we occupy the lowest level available for it.
101  * * when we encounter the "from" or "to" of an already seen
102  * refline, we free that level.
103  */
104 
106  if (!list) {
107  return NULL;
108  }
109  sten = rz_list_newf((RzListFree)free);
110  if (!sten) {
111  goto list_err;
112  }
114  /* analyze code block */
115  while (ptr < end && !rz_cons_is_breaked()) {
116  if (nlines != -1) {
117  if (!nlines) {
118  break;
119  }
120  nlines--;
121  }
122  if (analysis->maxreflines && count > analysis->maxreflines) {
123  break;
124  }
125  addr += sz;
126  {
127  RzPVector *metas = rz_meta_get_all_at(analysis, addr);
128  if (metas) {
129  void **it;
130  ut64 skip = 0;
131  rz_pvector_foreach (metas, it) {
132  RzIntervalNode *node = *it;
133  RzAnalysisMetaItem *meta = node->data;
134  switch (meta->type) {
135  case RZ_META_TYPE_DATA:
136  case RZ_META_TYPE_STRING:
137  case RZ_META_TYPE_HIDE:
138  case RZ_META_TYPE_FORMAT:
139  case RZ_META_TYPE_MAGIC:
140  skip = rz_meta_node_size(node);
141  goto do_skip;
142  default:
143  break;
144  }
145  }
146  do_skip:
148  if (skip) {
149  ptr += skip;
150  addr += skip;
151  goto __next;
152  }
153  }
154  }
155  if (!analysis->iob.is_valid_offset(analysis->iob.io, addr, RZ_PERM_X)) {
156  const int size = 4;
157  ptr += size;
158  addr += size;
159  goto __next;
160  }
161 
162  // This can segfault if opcode length and buffer check fails
164  rz_analysis_op(analysis, &op, addr, ptr, (int)(end - ptr), RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_HINT);
165  sz = op.size;
166  if (sz <= 0) {
167  sz = 1;
168  goto __next;
169  }
170 
171  /* store data */
172  switch (op.type) {
174  if (!linescall) {
175  break;
176  }
177  // fallthrough
180  if ((!linesout && (op.jump > opc + len || op.jump < opc)) || !op.jump) {
181  break;
182  }
183  if (!add_refline(list, sten, addr, op.jump, &count)) {
185  goto sten_err;
186  }
187  // add false branch in case its set and its not a call, useful for bf, maybe others
188  if (!op.delay && op.fail != UT64_MAX && op.fail != addr + op.size) {
189  if (!add_refline(list, sten, addr, op.fail, &count)) {
191  goto sten_err;
192  }
193  }
194  break;
196  RzAnalysisCaseOp *caseop;
197  RzListIter *iter;
198 
199  // add caseops
200  if (!op.switch_op) {
201  break;
202  }
203  rz_list_foreach (op.switch_op->cases, iter, caseop) {
204  if (!linesout && (op.jump > opc + len || op.jump < opc)) {
205  goto __next;
206  }
207  if (!add_refline(list, sten, op.switch_op->addr, caseop->jump, &count)) {
209  goto sten_err;
210  }
211  }
212  break;
213  }
214  }
215  __next:
216  ptr += sz;
217  }
220 
221  free_levels = RZ_NEWS0(ut8, rz_list_length(list) + 1);
222  if (!free_levels) {
223  goto sten_err;
224  }
225  int min = 0;
226 
227  rz_list_foreach (sten, iter, el) {
228  if ((el->is_from && el->r->level == -1) || (!el->is_from && el->r->level == -1)) {
229  el->r->level = min + 1;
230  free_levels[min] = 1;
231  if (min < 0) {
232  min = 0;
233  }
234  while (free_levels[++min] == 1) {
235  ;
236  }
237  } else {
238  free_levels[el->r->level - 1] = 0;
239  if (min > el->r->level - 1) {
240  min = el->r->level - 1;
241  }
242  }
243  }
244 
245  /* XXX: the algorithm can be improved. We can calculate the set of
246  * reflines used in each interval of addresses and store them.
247  * Considering rz_analysis_reflines_str is always called with increasing
248  * addresses, we can just traverse linearly the list of intervals to
249  * know which reflines need to be drawn for each address. In this way,
250  * we don't need to traverse again and again the reflines for each call
251  * to rz_analysis_reflines_str, but we can reuse the data already
252  * calculated. Those data will be quickly available because the
253  * intervals will be sorted and the addresses to consider are always
254  * increasing. */
255  free(free_levels);
256  rz_list_free(sten);
257  return list;
258 
259 sten_err:
260 list_err:
261  rz_list_free(sten);
263  return NULL;
264 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static ut64 opc
Definition: desil.c:33
void skip(file *in, unsigned n)
Definition: gzappend.c:202
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
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
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API RzPVector * rz_meta_get_all_at(RzAnalysis *a, ut64 at)
Definition: meta.c:219
RZ_API bool rz_analysis_op_fini(RzAnalysisOp *op)
Definition: op.c:37
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
#define min(a, b)
Definition: qsort.h:83
static bool add_refline(RzList *list, RzList *sten, ut64 addr, ut64 to, int *idx)
Definition: reflines.c:39
@ RZ_META_TYPE_DATA
Definition: rz_analysis.h:289
@ RZ_META_TYPE_HIDE
Definition: rz_analysis.h:294
@ RZ_META_TYPE_MAGIC
Definition: rz_analysis.h:293
@ RZ_META_TYPE_STRING
Definition: rz_analysis.h:291
@ RZ_META_TYPE_FORMAT
Definition: rz_analysis.h:292
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
@ RZ_ANALYSIS_OP_MASK_HINT
Definition: rz_analysis.h:443
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_SWITCH
Definition: rz_analysis.h:423
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define UT64_MAX
Definition: rz_types_base.h:86
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
RzAnalysisMetaType type
Definition: rz_analysis.h:302
RzIOBind iob
Definition: rz_analysis.h:574
RzIOIsValidOff is_valid_offset
Definition: rz_io.h:257
RzIO * io
Definition: rz_io.h:232
static struct Type metas[]
Definition: swift.c:39
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References add_refline(), addr, count, rz_interval_node_t::data, test_evm::end, free(), rz_io_bind_t::io, rz_analysis_t::iob, refline_end::is_from, rz_io_bind_t::is_valid_offset, rz_analysis_case_obj_t::jump, len, rz_analysis_refline_t::level, list(), rz_analysis_t::maxreflines, memset(), metas, min, NULL, op, opc, refline_end::r, rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_SWITCH, rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_list_free(), rz_list_length(), rz_list_newf(), rz_meta_get_all_at(), RZ_META_TYPE_DATA, RZ_META_TYPE_FORMAT, RZ_META_TYPE_HIDE, RZ_META_TYPE_MAGIC, RZ_META_TYPE_STRING, RZ_NEWS0, RZ_PERM_X, rz_pvector_foreach, rz_pvector_free(), skip(), rz_analysis_meta_item_t::type, ut64(), and UT64_MAX.

Referenced by ds_reflines_init().

◆ rz_analysis_reflines_middle()

RZ_API int rz_analysis_reflines_middle ( RzAnalysis a,
RzList list,
ut64  addr,
int  len 
)

Definition at line 266 of file reflines.c.

266  {
267  if (a && list) {
268  RzAnalysisRefline *ref;
269  RzListIter *iter;
270  rz_list_foreach (list, iter, ref) {
271  if ((ref->to > addr) && (ref->to < addr + len)) {
272  return true;
273  }
274  }
275  }
276  return false;
277 }

References a, addr, len, list(), and rz_analysis_refline_t::to.

Referenced by ds_adistrick_comments().

◆ rz_analysis_reflines_str()

RZ_API RzAnalysisRefStr* rz_analysis_reflines_str ( void *  _core,
ut64  addr,
int  opts 
)

Definition at line 344 of file reflines.c.

344  {
345  RzCore *core = _core;
346  RzCons *cons = core->cons;
347  RzAnalysis *analysis = core->analysis;
348  RzBuffer *b;
349  RzBuffer *c;
350  RzListIter *iter;
351  RzAnalysisRefline *ref;
352  int l;
353  bool wide = opts & RZ_ANALYSIS_REFLINE_TYPE_WIDE;
354  int dir = 0, pos = -1, max_level = -1;
355  bool middle_before = opts & RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_BEFORE;
356  bool middle_after = opts & RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_AFTER;
357  char *str = NULL;
358  char *col_str = NULL;
359 
360  rz_return_val_if_fail(cons && analysis && analysis->reflines, NULL);
361 
362  RzList *lvls = rz_list_new();
363  if (!lvls) {
364  return NULL;
365  }
366  rz_list_foreach (analysis->reflines, iter, ref) {
367  if (core->cons && core->cons->context->breaked) {
368  rz_list_free(lvls);
369  return NULL;
370  }
371  if (in_refline(addr, ref) && refline_kept(ref, middle_after, addr)) {
373  }
374  }
377  rz_buf_append_string(c, " ");
378  rz_buf_append_string(b, " ");
379  rz_list_foreach (lvls, iter, ref) {
380  if (core->cons && core->cons->context->breaked) {
381  rz_list_free(lvls);
382  rz_buf_free(b);
383  rz_buf_free(c);
384  return NULL;
385  }
386  if ((ref->from == addr || ref->to == addr) && !middle_after) {
387  const char *corner = get_corner_char(ref, addr, middle_before);
388  const char ch = ref->from == addr ? '=' : '-';
389  const char ch_col = ref->from >= ref->to ? 't' : 'd';
390  const char *col = (ref->from >= ref->to) ? "t" : "d";
391  if (!pos) {
392  int ch_pos = max_level + 1 - ref->level;
393  if (wide) {
394  ch_pos = ch_pos * 2 - 1;
395  }
396  rz_buf_write_at(b, ch_pos, (ut8 *)corner, 1);
397  rz_buf_write_at(c, ch_pos, (ut8 *)col, 1);
398  fill_level(b, ch_pos + 1, ch, ref, wide);
399  fill_level(c, ch_pos + 1, ch_col, ref, wide);
400  } else {
401  add_spaces(b, ref->level, pos, wide);
402  add_spaces(c, ref->level, pos, wide);
403  rz_buf_append_string(b, corner);
404  rz_buf_append_string(c, col);
405  if (!middle_before) {
406  fill_level(b, -1, ch, ref, wide);
407  fill_level(c, -1, ch_col, ref, wide);
408  }
409  }
410  if (!middle_before) {
411  dir = ref->to == addr ? 1 : 2;
412  }
413  pos = middle_before ? ref->level : 0;
414  } else {
415  if (!pos) {
416  continue;
417  }
418  add_spaces(b, ref->level, pos, wide);
419  add_spaces(c, ref->level, pos, wide);
420  if (ref->from >= ref->to) {
421  rz_buf_append_string(b, ":");
422  rz_buf_append_string(c, "t");
423  } else {
424  rz_buf_append_string(b, "|");
425  rz_buf_append_string(c, "d");
426  }
427  pos = ref->level;
428  }
429  if (max_level == -1) {
430  max_level = ref->level;
431  }
432  }
433  add_spaces(c, 0, pos, wide);
434  add_spaces(b, 0, pos, wide);
436  col_str = rz_buf_to_string(c);
437  rz_buf_free(b);
438  rz_buf_free(c);
439  b = NULL;
440  c = NULL;
441  if (!str || !col_str) {
442  rz_list_free(lvls);
443  // rz_buf_free_to_string already free b and if that is the case
444  // b will be NULL and rz_buf_free will return but if there was
445  // an error we free b here so in other words is safe
446  rz_buf_free(b);
447  rz_buf_free(c);
448  return NULL;
449  }
450  if (core->analysis->lineswidth > 0) {
451  int lw = core->analysis->lineswidth;
452  l = strlen(str);
453  if (l > lw) {
454  rz_str_cpy(str, str + l - lw);
455  rz_str_cpy(col_str, col_str + l - lw);
456  } else {
457  char pfx[128];
458  lw -= l;
459  memset(pfx, ' ', sizeof(pfx));
460  if (lw >= sizeof(pfx)) {
461  lw = sizeof(pfx) - 1;
462  }
463  if (lw > 0) {
464  pfx[lw] = 0;
465  str = rz_str_prepend(str, pfx);
466  col_str = rz_str_prepend(col_str, pfx);
467  }
468  }
469  }
470  const char prev_col = col_str[strlen(col_str) - 1];
471  const char *arr_col = prev_col == 't' ? "tt " : "dd ";
472  str = rz_str_append(str, (dir == 1) ? "-> " : (dir == 2) ? "=< "
473  : " ");
474  col_str = rz_str_append(col_str, arr_col);
475 
476  rz_list_free(lvls);
478  out->str = str;
479  out->cols = col_str;
480  return out;
481 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
static RzCore * _core
Definition: cmd_debug.c:1622
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
static const char * get_corner_char(RzAnalysisRefline *ref, ut64 addr, bool is_middle_before)
Definition: reflines.c:279
static void add_spaces(RzBuffer *b, int level, int pos, bool wide)
Definition: reflines.c:298
static void fill_level(RzBuffer *b, int pos, char ch, RzAnalysisRefline *r, bool wide)
Definition: reflines.c:311
static bool refline_kept(RzAnalysisRefline *ref, bool middle_after, ut64 addr)
Definition: reflines.c:327
#define in_refline(a, r)
Definition: reflines.c:12
static int cmp_by_ref_lvl(const RzAnalysisRefline *a, const RzAnalysisRefline *b)
Definition: reflines.c:24
@ RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_BEFORE
Definition: rz_analysis.h:467
@ RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_AFTER
Definition: rz_analysis.h:469
@ RZ_ANALYSIS_REFLINE_TYPE_WIDE
Definition: rz_analysis.h:466
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API RZ_OWN char * rz_buf_to_string(RZ_NONNULL RzBuffer *b)
Stringify the buffer.
Definition: buf.c:642
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
#define rz_str_cpy(x, y)
Definition: rz_str.h:109
RZ_API char * rz_str_prepend(char *ptr, const char *string)
Definition: str.c:1027
#define c(i)
Definition: sha256.c:43
RzList * reflines
Definition: rz_analysis.h:609
RzConsContext * context
Definition: rz_cons.h:502
RzCons * cons
Definition: rz_core.h:312
RzAnalysis * analysis
Definition: rz_core.h:322

References _core, add_spaces(), addr, rz_core_t::analysis, b, rz_cons_context_t::breaked, c, cmp_by_ref_lvl(), rz_core_t::cons, rz_cons_t::context, fill_level(), rz_analysis_refline_t::from, get_corner_char(), in_refline, rz_analysis_refline_t::level, rz_analysis_t::lineswidth, memset(), NULL, out, pos, refline_kept(), rz_analysis_t::reflines, RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_AFTER, RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_BEFORE, RZ_ANALYSIS_REFLINE_TYPE_WIDE, rz_buf_append_string(), rz_buf_free(), rz_buf_new_with_bytes(), rz_buf_to_string(), rz_buf_write_at(), rz_list_add_sorted(), rz_list_free(), rz_list_new(), RZ_NEW0, rz_return_val_if_fail, rz_str_append(), rz_str_cpy, rz_str_prepend(), cmd_descs_generate::str, and rz_analysis_refline_t::to.

Referenced by ds_begin_cont(), and ds_update_ref_lines().

◆ rz_analysis_reflines_str_free()

RZ_API void rz_analysis_reflines_str_free ( RzAnalysisRefStr refstr)

Definition at line 483 of file reflines.c.

483  {
484  free(refstr->str);
485  free(refstr->cols);
486  free(refstr);
487 }

References rz_analysis_ref_char::cols, free(), and rz_analysis_ref_char::str.

Referenced by ds_begin_cont().