@@ -30,6 +30,7 @@ addr_t dis_options_offset = R_BINFMT_BAD_OFFSET;
30
30
u64 dis_options_len = 0 ;
31
31
r_binfmt_arch_e dis_options_arch = R_BINFMT_TYPE_UNDEF ;
32
32
r_disa_flavor_e dis_options_flavor = R_DISA_FLAVOR_INTEL ;
33
+ const char * dis_options_sym = NULL ;
33
34
34
35
/* Print disassemble help */
35
36
void dis_help (void ) {
@@ -39,6 +40,7 @@ void dis_help(void) {
39
40
printf (" --no-color, -N Do not colorize output\n" );
40
41
printf (" --address, -a <a> Start disassembling at address <a>\n" );
41
42
printf (" --offset, -o <o> Start disassembling at offset <o>\n" );
43
+ printf (" --sym, -s <s> Disassemble symbol\n" );
42
44
printf (" --len, -l <l> Disassemble only <l> bytes\n" );
43
45
printf (" --arch, -A <a> Select architecture (x86, x86-64, arm, arm64)\n" );
44
46
printf (" --flavor, -f <f> Change flavor (intel, att)\n" );
@@ -53,6 +55,7 @@ void dis_options_parse(int argc, char **argv) {
53
55
const struct option opts [] = {
54
56
{"address" , required_argument , NULL , 'a' },
55
57
{"arch" , required_argument , NULL , 'A' },
58
+ {"sym" , required_argument , NULL , 's' },
56
59
{"flavor" , required_argument , NULL , 'f' },
57
60
{"help" , no_argument , NULL , 'h' },
58
61
{"len" , required_argument , NULL , 'l' },
@@ -61,13 +64,17 @@ void dis_options_parse(int argc, char **argv) {
61
64
{NULL , 0 , NULL , 0 }
62
65
};
63
66
64
- while ((opt = getopt_long (argc , argv , "a:A:f:hl:No:" , opts , NULL )) != -1 ) {
67
+ while ((opt = getopt_long (argc , argv , "a:A:s: f:hl:No:" , opts , NULL )) != -1 ) {
65
68
switch (opt ) {
66
69
67
70
case 'a' :
68
71
dis_options_address = strtoull (optarg , NULL , 0 );
69
72
break ;
70
73
74
+ case 's' :
75
+ dis_options_sym = optarg ;
76
+ break ;
77
+
71
78
case 'A' :
72
79
dis_options_arch = r_binfmt_string_to_arch (optarg );
73
80
if (dis_options_arch == R_BINFMT_ARCH_UNDEF )
@@ -106,19 +113,16 @@ void dis_options_parse(int argc, char **argv) {
106
113
if (optind < argc ) {
107
114
dis_options_filename = argv [optind ];
108
115
}
109
-
110
- if (dis_options_offset != R_BINFMT_BAD_OFFSET &&
111
- dis_options_address != R_BINFMT_BAD_ADDR )
112
- R_UTILS_ERR ("You must specify offset or address, not twice !" );
113
116
}
114
117
115
118
/* Disassemble binary at specified address */
116
- void dis_address (r_disa_s * dis , r_binfmt_s * bin , addr_t addr , u64 len ) {
119
+ void dis_address (r_disa_s * dis , r_binfmt_s * bin , addr_t addr , u64 len , int stop_next_sym ) {
117
120
r_binfmt_mem_s * m ;
118
121
r_disa_instr_t * instr ;
119
122
const char * sym ;
120
123
u64 length ;
121
124
u64 off ;
125
+ int sym_processed = 0 ;
122
126
123
127
/* Test every loadable segment */
124
128
for (m = bin -> mlist -> head ; m ; m = m -> next ) {
@@ -142,6 +146,12 @@ void dis_address(r_disa_s *dis, r_binfmt_s *bin, addr_t addr, u64 len) {
142
146
143
147
/* Print symbol, if it exists */
144
148
if ((sym = r_binfmt_get_sym_by_addr (bin , instr -> address )) != NULL ) {
149
+ if (stop_next_sym ) {
150
+ if (sym_processed > 0 )
151
+ return ;
152
+ else
153
+ sym_processed ++ ;
154
+ }
145
155
R_UTILS_PRINT_YELLOW_BG_BLACK (dis_options_color , "\n<%s>:\n" , sym );
146
156
}
147
157
@@ -207,6 +217,8 @@ void dis_offset(r_disa_s *dis, r_binfmt_s *bin, u64 offset, u64 len) {
207
217
208
218
/* Main function of disassemble command */
209
219
void dis_cmd (int argc , char * * argv ) {
220
+ int stop_next_sym = 0 ;
221
+ addr_t sym ;
210
222
r_binfmt_s bin ;
211
223
r_disa_s dis ;
212
224
@@ -221,16 +233,29 @@ void dis_cmd(int argc, char **argv) {
221
233
if (!r_disa_set_flavor (& dis , dis_options_flavor ))
222
234
R_UTILS_ERR ("Can't set flavor" );
223
235
236
+ /* Try to find symbol, if option is set */
237
+ if (dis_options_sym != NULL ) {
238
+ if ((sym = r_binfmt_get_sym_by_name (& bin , dis_options_sym )) == R_BINFMT_BAD_ADDR )
239
+ R_UTILS_ERR ("Symbol <%s> not found" , dis_options_sym );
240
+ dis_options_address = sym ;
241
+ stop_next_sym = 1 ;
242
+ }
243
+
244
+ /* Can't disassemble offset + address at the same time */
245
+ if (dis_options_offset != R_BINFMT_BAD_OFFSET &&
246
+ dis_options_address != R_BINFMT_BAD_ADDR )
247
+ R_UTILS_ERR ("You must specify offset or address, not twice !" );
248
+
224
249
/* First, try disassemble at offset */
225
250
if (dis_options_offset != R_BINFMT_BAD_OFFSET ) {
226
251
dis_offset (& dis , & bin , dis_options_offset , dis_options_len );
227
252
} else {
228
253
/* Now check if address if specified */
229
254
if (dis_options_address != R_BINFMT_BAD_ADDR ) {
230
- dis_address (& dis , & bin , dis_options_address , dis_options_len );
255
+ dis_address (& dis , & bin , dis_options_address , dis_options_len , stop_next_sym );
231
256
/* If not, try to disassemble starting at entry point */
232
257
} else if (bin .entry != 0 ) {
233
- dis_address (& dis , & bin , bin .entry , dis_options_len );
258
+ dis_address (& dis , & bin , bin .entry , dis_options_len , stop_next_sym );
234
259
/* Entry point is bad...Start at beginning of the file */
235
260
} else {
236
261
dis_offset (& dis , & bin , 0 , dis_options_len );
0 commit comments