Rizin
unix-like reverse engineering framework and cli tools
dbginfo.c File Reference
#include <rz_types.h>
#include <rz_bin.h>

Go to the source code of this file.

Macros

#define CMP(x, y)   (x > y.address ? 1 : (x < y.address ? -1 : 0))
 

Functions

RZ_API void rz_bin_source_line_info_builder_init (RzBinSourceLineInfoBuilder *builder)
 
RZ_API void rz_bin_source_line_info_builder_fini (RzBinSourceLineInfoBuilder *builder)
 
RZ_API void rz_bin_source_line_info_builder_push_sample (RzBinSourceLineInfoBuilder *builder, ut64 address, ut32 line, ut32 column, const char *file)
 Push a new sample into the builder. More...
 
static int line_sample_cmp (const void *a, const void *b)
 
RZ_API RzBinSourceLineInforz_bin_source_line_info_builder_build_and_fini (RzBinSourceLineInfoBuilder *builder)
 
RZ_API void rz_bin_source_line_info_free (RzBinSourceLineInfo *sli)
 
RZ_API const RzBinSourceLineSamplerz_bin_source_line_info_get_first_at (const RzBinSourceLineInfo *sli, ut64 addr)
 Find the first sample that affects the given address. i.e. find the first sample with the highest address less or equal to addr. There may be more which can be retrieved by repeatedly calling rz_bin_source_line_info_get_next() until it returns NULL. More...
 
RZ_API const RzBinSourceLineSamplerz_bin_source_line_info_get_next (const RzBinSourceLineInfo *sli, RZ_NONNULL const RzBinSourceLineSample *cur)
 
RZ_DEPRECATE RZ_API bool rz_bin_addr2line (RzBin *bin, ut64 addr, char *file, int len, int *line)
 
RZ_DEPRECATE RZ_API char * rz_bin_addr2text (RzBin *bin, ut64 addr, int origin)
 

Macro Definition Documentation

◆ CMP

#define CMP (   x,
 
)    (x > y.address ? 1 : (x < y.address ? -1 : 0))

Function Documentation

◆ line_sample_cmp()

static int line_sample_cmp ( const void *  a,
const void *  b 
)
static

Definition at line 39 of file dbginfo.c.

39  {
40  const RzBinSourceLineSample *sa = a;
41  const RzBinSourceLineSample *sb = b;
42  // first, sort by addr
43  if (sa->address < sb->address) {
44  return -1;
45  }
46  if (sa->address > sb->address) {
47  return 1;
48  }
49  // closing samples are always equal (rest of their fields are ignored anyway)
51  return 0;
52  }
53  // push closing samples to the back, which is necessary to skip them during packing
55  return 1;
56  }
58  return -1;
59  }
60  // then sort by line
61  if (sa->line < sb->line) {
62  return -1;
63  }
64  if (sa->line > sb->line) {
65  return 1;
66  }
67  // then by column
68  if (sa->column < sb->column) {
69  return -1;
70  }
71  if (sa->column > sb->column) {
72  return 1;
73  }
74  // and eventually by file because this is the most exponsive operation
75  if (!sa->file && !sb->file) {
76  return 0;
77  }
78  if (!sa->file) {
79  return -1;
80  }
81  if (!sb->file) {
82  return 1;
83  }
84  return strcmp(sa->file, sb->file);
85 }
static SblHeader sb
Definition: bin_mbn.c:26
static bool rz_bin_source_line_sample_is_closing(const RzBinSourceLineSample *s)
Definition: rz_bin.h:474
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41
A single sample of source line info for a specific address.
Definition: rz_bin.h:441

References a, rz_bin_source_line_sample_t::address, b, rz_bin_source_line_sample_t::column, rz_bin_source_line_sample_t::file, rz_bin_source_line_sample_t::line, rz_bin_source_line_sample_is_closing(), and sb.

Referenced by rz_bin_source_line_info_builder_build_and_fini().

◆ rz_bin_addr2line()

RZ_DEPRECATE RZ_API bool rz_bin_addr2line ( RzBin bin,
ut64  addr,
char *  file,
int  len,
int line 
)

Definition at line 194 of file dbginfo.c.

194  {
195  rz_return_val_if_fail(bin, false);
196  if (!bin->cur || !bin->cur->o || !bin->cur->o->lines) {
197  return false;
198  }
200  if (!s || s->address != addr) {
201  // consider only exact matches, not inside of samples
202  return false;
203  }
204  if (line) {
205  *line = s->line;
206  }
207  if (file && len) {
208  if (s->file) {
209  rz_str_ncpy(file, s->file, len);
210  } else {
211  *file = 0;
212  }
213  }
214  return false;
215 }
size_t len
Definition: 6502dis.c:15
RZ_API const RzBinSourceLineSample * rz_bin_source_line_info_get_first_at(const RzBinSourceLineInfo *sli, ut64 addr)
Find the first sample that affects the given address. i.e. find the first sample with the highest add...
Definition: dbginfo.c:151
line
Definition: setup.py:34
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
Definition: str.c:923
Definition: malloc.c:26
Definition: gzappend.c:170
static int addr
Definition: z80asm.c:58

References addr, len, setup::line, rz_bin_source_line_info_get_first_at(), rz_return_val_if_fail, rz_str_ncpy(), and s.

Referenced by core_analysis_graph_label(), and step_line().

◆ rz_bin_addr2text()

RZ_DEPRECATE RZ_API char* rz_bin_addr2text ( RzBin bin,
ut64  addr,
int  origin 
)

Definition at line 217 of file dbginfo.c.

217  {
219  if (!bin->cur || !bin->cur->o || !bin->cur->o->lines) {
220  return NULL;
221  }
223  if (s && s->address != addr) {
224  // consider only exact matches, not inside of samples
225  return NULL;
226  }
227  while (s && !s->file) {
228  s = rz_bin_source_line_info_get_next(bin->cur->o->lines, s);
229  }
230  if (!s) {
231  return NULL;
232  }
233  const char *file_nopath;
234  if (origin > 1) {
235  file_nopath = s->file;
236  } else {
237  file_nopath = strrchr(s->file, '/');
238  if (file_nopath) {
239  file_nopath++;
240  } else {
241  file_nopath = s->file;
242  }
243  }
244  if (!s->line) {
245  return strdup(file_nopath);
246  }
247  char *out = rz_file_slurp_line(s->file, s->line, 0);
248  if (out) {
249  rz_str_trim(out);
250  if (origin) {
251  char *res = rz_str_newf("%s:%d %s",
252  file_nopath, s->line,
253  out ? out : "");
254  free(out);
255  out = res;
256  }
257  return out;
258  }
259  return rz_str_newf("%s:%" PFMT32u, file_nopath, s->line);
260 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
#define NULL
Definition: cris-opc.c:27
RZ_API const RzBinSourceLineSample * rz_bin_source_line_info_get_next(const RzBinSourceLineInfo *sli, RZ_NONNULL const RzBinSourceLineSample *cur)
Definition: dbginfo.c:182
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf uLong int origin
Definition: ioapi.h:144
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")
RZ_API bool RZ_API char * rz_file_slurp_line(const char *file, int line, int context)
Definition: file.c:673
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
#define PFMT32u
Definition: rz_types.h:409

References addr, free(), NULL, out, PFMT32u, rz_bin_source_line_info_get_first_at(), rz_bin_source_line_info_get_next(), rz_file_slurp_line(), rz_return_val_if_fail, rz_str_newf(), rz_str_trim(), s, and strdup().

Referenced by ds_print_dwarf(), and rabin_show_srcline().

◆ rz_bin_source_line_info_builder_build_and_fini()

RZ_API RzBinSourceLineInfo* rz_bin_source_line_info_builder_build_and_fini ( RzBinSourceLineInfoBuilder builder)

Definition at line 87 of file dbginfo.c.

87  {
89  if (!r) {
90  goto err;
91  }
92  size_t initial_samples_count = rz_vector_len(&builder->samples); // final count may be less after removing unnecessary closing samples
93  if (initial_samples_count) {
94  r->samples = RZ_NEWS0(RzBinSourceLineSample, initial_samples_count);
95  if (!r->samples) {
96  goto err_r;
97  }
98 
99  // samples should be built in flat RzVector to avoid excessive small mallocs,
100  // for sorting we use a pvector with references into our flat vectors (after flushing them).
101 
102  RzPVector sorter;
103  rz_pvector_init(&sorter, NULL);
104  RzBinSourceLineSample *initial_samples = rz_vector_flush(&builder->samples);
105  rz_pvector_reserve(&sorter, initial_samples_count);
106  for (size_t i = 0; i < initial_samples_count; i++) {
107  rz_pvector_push(&sorter, &initial_samples[i]);
108  }
110 
111  r->samples_count = 0;
112  for (size_t i = 0; i < initial_samples_count; i++) {
113  RzBinSourceLineSample *new_sample = rz_pvector_at(&sorter, i);
114  if (r->samples_count) {
115  RzBinSourceLineSample *prev = &r->samples[r->samples_count - 1];
116  if (prev->address == new_sample->address && rz_bin_source_line_sample_is_closing(new_sample)) {
117  // closing sample but there are others that are not closing so this is dropped
118  continue;
119  }
120  }
121  r->samples[r->samples_count++] = *new_sample;
122  }
123  free(initial_samples); // all inner strings are moved already
124  rz_pvector_fini(&sorter);
125  }
126  r->filename_pool = builder->filename_pool;
127  // don't call regular fini on the builder because we moved its string pool!
128  rz_vector_fini(&builder->samples);
129  return r;
130 err_r:
131  free(r);
132 err:
134  return NULL;
135 }
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
#define r
Definition: crypto_rc6.c:12
static int line_sample_cmp(const void *a, const void *b)
Definition: dbginfo.c:39
RZ_API void rz_bin_source_line_info_builder_fini(RzBinSourceLineInfoBuilder *builder)
Definition: dbginfo.c:14
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
static void ** rz_pvector_reserve(RzPVector *vec, size_t capacity)
Definition: rz_vector.h:312
RZ_API void rz_pvector_sort(RzPVector *vec, RzPVectorComparator cmp)
Definition: vector.c:408
RZ_API void * rz_vector_flush(RzVector *vec)
Turn the vector into a fixed-size array. This will clear the vector and return an array of its origin...
Definition: vector.c:230
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
RZ_API void rz_pvector_fini(RzPVector *vec)
Definition: vector.c:331
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
RzStrConstPool filename_pool
Definition: rz_bin.h:496

References rz_bin_source_line_sample_t::address, err, rz_bin_source_line_info_builder_t::filename_pool, free(), i, line_sample_cmp(), NULL, r, rz_bin_source_line_info_builder_fini(), rz_bin_source_line_sample_is_closing(), RZ_NEW0, RZ_NEWS0, rz_pvector_at(), rz_pvector_fini(), rz_pvector_init(), rz_pvector_push(), rz_pvector_reserve(), rz_pvector_sort(), rz_vector_fini(), rz_vector_flush(), rz_vector_len(), and rz_bin_source_line_info_builder_t::samples.

Referenced by lines(), and parse_line_raw().

◆ rz_bin_source_line_info_builder_fini()

RZ_API void rz_bin_source_line_info_builder_fini ( RzBinSourceLineInfoBuilder builder)

Definition at line 14 of file dbginfo.c.

14  {
15  rz_vector_fini(&builder->samples);
17 }
RZ_API void rz_str_constpool_fini(RzStrConstPool *pool)
Definition: str_constpool.c:15

References rz_bin_source_line_info_builder_t::filename_pool, rz_str_constpool_fini(), rz_vector_fini(), and rz_bin_source_line_info_builder_t::samples.

Referenced by rz_bin_source_line_info_builder_build_and_fini().

◆ rz_bin_source_line_info_builder_init()

RZ_API void rz_bin_source_line_info_builder_init ( RzBinSourceLineInfoBuilder builder)

Definition at line 9 of file dbginfo.c.

9  {
12 }
RZ_API bool rz_str_constpool_init(RzStrConstPool *pool)
Definition: str_constpool.c:10
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33

References rz_bin_source_line_info_builder_t::filename_pool, NULL, rz_str_constpool_init(), rz_vector_init(), and rz_bin_source_line_info_builder_t::samples.

Referenced by lines(), and parse_line_raw().

◆ rz_bin_source_line_info_builder_push_sample()

RZ_API void rz_bin_source_line_info_builder_push_sample ( RzBinSourceLineInfoBuilder builder,
ut64  address,
ut32  line,
ut32  column,
const char *  file 
)

Push a new sample into the builder.

This function is used to continuously fill the builder with concrete samples of line info for a specific address, usually during parsing of debug info from a file. The samples may be pushed in any order and the builder will later take care of generating a valid RzBinSourceLineInfo from it.

Parameters
linemay be 0 or a positive line number, where 0 means that this entry closes the one before it. see also RzBinSourceLine.

Definition at line 28 of file dbginfo.c.

28  {
29  RzBinSourceLineSample *sample = rz_vector_push(&builder->samples, NULL);
30  if (!sample) {
31  return;
32  }
33  sample->address = address;
34  sample->line = line;
35  sample->column = column;
36  sample->file = file ? rz_str_constpool_get(&builder->filename_pool, file) : NULL;
37 }
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
Definition: str_constpool.c:19
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197

References rz_bin_source_line_sample_t::address, rz_bin_source_line_sample_t::column, rz_bin_source_line_sample_t::file, rz_bin_source_line_info_builder_t::filename_pool, rz_bin_source_line_sample_t::line, setup::line, NULL, rz_str_constpool_get(), rz_vector_push(), and rz_bin_source_line_info_builder_t::samples.

Referenced by lines(), rz_bin_dwarf_line_op_run(), and store_line_sample().

◆ rz_bin_source_line_info_free()

RZ_API void rz_bin_source_line_info_free ( RzBinSourceLineInfo sli)

Definition at line 137 of file dbginfo.c.

137  {
138  if (!sli) {
139  return;
140  }
141  free(sli->samples);
143  free(sli);
144 }
RzStrConstPool filename_pool
Definition: rz_bin.h:488
RzBinSourceLineSample * samples
All source line references for given adresses.
Definition: rz_bin.h:486

References rz_bin_source_line_info_t::filename_pool, free(), rz_str_constpool_fini(), and rz_bin_source_line_info_t::samples.

Referenced by rz_bin_dwarf_line_info_free(), and rz_bin_object_free().

◆ rz_bin_source_line_info_get_first_at()

RZ_API const RzBinSourceLineSample* rz_bin_source_line_info_get_first_at ( const RzBinSourceLineInfo sli,
ut64  addr 
)

Find the first sample that affects the given address. i.e. find the first sample with the highest address less or equal to addr. There may be more which can be retrieved by repeatedly calling rz_bin_source_line_info_get_next() until it returns NULL.

Definition at line 151 of file dbginfo.c.

151  {
152  if (!sli->samples_count) {
153  return NULL;
154  }
155  size_t l;
156 #define CMP(x, y) (x > y.address ? 1 : (x < y.address ? -1 : 0))
158 #undef CMP
159  if (!l) {
160  return NULL;
161  }
162  l--;
163  RzBinSourceLineSample *r = &sli->samples[l];
164  if (r->address > addr || rz_bin_source_line_sample_is_closing(r)) {
165  return NULL;
166  }
167  // walk back to the very first entry with this addr
168  while (r > sli->samples) {
169  if ((r - 1)->address == r->address) {
170  r--;
171  } else {
172  break;
173  }
174  }
175  return r;
176 }
#define CMP(x, y)
#define rz_array_upper_bound(array, len, x, i, cmp)
Definition: rz_vector.h:374

References addr, CMP, NULL, r, rz_array_upper_bound, rz_bin_source_line_sample_is_closing(), rz_bin_source_line_info_t::samples, and rz_bin_source_line_info_t::samples_count.

Referenced by print_source_info(), rz_bin_addr2line(), and rz_bin_addr2text().

◆ rz_bin_source_line_info_get_next()

RZ_API const RzBinSourceLineSample* rz_bin_source_line_info_get_next ( const RzBinSourceLineInfo sli,
RZ_NONNULL const RzBinSourceLineSample cur 
)
Parameters
curMUST be a pointer returned by either rz_bin_source_line_info_get_first_at() or rz_bin_source_line_info_get_next().
Returns
The next sample at the same address as cur or NULL if there is none.

Definition at line 182 of file dbginfo.c.

182  {
183  rz_return_val_if_fail(sli && cur && cur >= sli->samples && cur < sli->samples + sli->samples_count, NULL);
184  if (cur == sli->samples + sli->samples_count - 1) {
185  return NULL;
186  }
187  const RzBinSourceLineSample *next = cur + 1;
188  if (next->address != cur->address) {
189  return NULL;
190  }
191  return next;
192 }

References rz_bin_source_line_sample_t::address, NULL, rz_return_val_if_fail, rz_bin_source_line_info_t::samples, and rz_bin_source_line_info_t::samples_count.

Referenced by print_source_info(), and rz_bin_addr2text().