@@ -79,3 +79,142 @@ R_API char *r_asm_parse_patch(RAsm *a, RAnalOp *aop, const char *op) {
7979 }
8080 return NULL ;
8181}
82+
83+ // TODO: R2_600 - finish reimplementing libr/core/disasm.c: ds_sub_jumps
84+ R_API char * r_asm_parse_subjmp (RAsm * a , RAnalOp * aop , const char * op ) {
85+ R_RETURN_VAL_IF_FAIL (a , false);
86+ const char * arch = R_UNWRAP3 (a , config , arch );
87+ const bool x86 = arch && r_str_startswith (arch , "x86" );
88+ const char * name = NULL ;
89+ const char * kw = "" ;
90+ ut64 addr = aop -> jump ;
91+ int optype = aop -> type & R_ANAL_OP_TYPE_MASK ;
92+ switch (optype ) {
93+ case R_ANAL_OP_TYPE_LEA :
94+ if (x86 ) {
95+ // let the pseudo plugin trim the '[]'
96+ return NULL ;
97+ }
98+ // for ARM adrp, section is better than adrp, segment
99+ break ;
100+ case R_ANAL_OP_TYPE_JMP :
101+ case R_ANAL_OP_TYPE_CJMP :
102+ case R_ANAL_OP_TYPE_MOV :
103+ case R_ANAL_OP_TYPE_MJMP :
104+ break ;
105+ case R_ANAL_OP_TYPE_PUSH :
106+ addr = aop -> val ;
107+ if (addr < 10 ) {
108+ // ignore push 0
109+ return NULL ;
110+ }
111+ break ;
112+ case R_ANAL_OP_TYPE_CALL :
113+ case R_ANAL_OP_TYPE_UJMP :
114+ case R_ANAL_OP_TYPE_UCALL :
115+ break ;
116+ default :
117+ return NULL ;
118+ }
119+ #if 0
120+ RFlag * f = ds -> core -> flags ;
121+ RAnal * anal = ds -> core -> anal ;
122+ RBinReloc * rel = NULL ;
123+ RBinObject * bo = r_bin_cur_object (ds -> core -> bin );
124+ if (bo && !bo -> is_reloc_patched ) {
125+ rel = r_core_getreloc (ds -> core , ds -> analop .addr , ds -> analop .size );
126+ }
127+ if (!rel ) {
128+ rel = r_core_getreloc (ds -> core , addr , ds -> analop .size );
129+ if (!rel ) {
130+ // some jmp 0 are actually relocs, so we can just ignore it
131+ if (!addr || addr == UT64_MAX ) {
132+ rel = r_core_getreloc (ds -> core , ds -> analop .ptr , ds -> analop .size );
133+ if (rel ) {
134+ addr = ds -> analop .ptr ;
135+ }
136+ }
137+ }
138+ }
139+ if (addr == UT64_MAX ) {
140+ if (rel ) {
141+ addr = 0 ;
142+ } else {
143+ addr = ds -> analop .ptr ;
144+ }
145+ }
146+ RAnalFunction * fcn = r_anal_get_function_at (anal , addr );
147+ if (fcn ) {
148+ name = fcn -> name ;
149+ } else {
150+ if (rel ) {
151+ if (rel && rel -> import && rel -> import -> name ) {
152+ name = r_bin_name_tostring (rel -> import -> name );
153+ } else if (rel && rel -> symbol && rel -> symbol -> name ) {
154+ name = r_bin_name_tostring (rel -> symbol -> name );
155+ }
156+ if (addr ) { // && *name == '.') {
157+ RFlagItem * flag = r_core_flag_get_by_spaces (f , false, addr );
158+ if (flag ) {
159+ if (!r_str_startswith (flag -> name , "section" )) {
160+ name = flag -> name ;
161+ if (f -> realnames && flag -> realname ) {
162+ name = flag -> realname ;
163+ }
164+ }
165+ }
166+ }
167+ } else {
168+ RFlagItem * flag = r_core_flag_get_by_spaces (f , false, addr );
169+ if (flag ) {
170+ // R2R db/anal/jmptbl
171+ // adrp x0, segment.DATA //instead-of// adrp x0, section.20.__DATA.__objc_const
172+ if (!r_str_startswith (flag -> name , "section" )) {
173+ name = flag -> name ;
174+ if (f -> realnames && flag -> realname ) {
175+ name = flag -> realname ;
176+ }
177+ }
178+ }
179+ }
180+ }
181+ if (name ) {
182+ char * nptr ;
183+ ut64 numval ;
184+ char * hstr = strdup (str );
185+ char * ptr = hstr ;
186+ const int bits = ds -> core -> rasm -> config -> bits ;
187+ const int seggrn = ds -> core -> rasm -> config -> seggrn ;
188+ while ((nptr = _find_next_number (ptr ))) {
189+ ptr = nptr ;
190+ char * colon = strchr (ptr , ':' );
191+ if (x86 && bits == 16 && colon ) {
192+ * colon = '\0' ;
193+ ut64 seg = r_num_get (NULL , ptr );
194+ ut64 off = r_num_get (NULL , colon + 1 );
195+ * colon = ':' ;
196+ numval = (seg << seggrn ) + off ;
197+ } else {
198+ numval = r_num_get (NULL , ptr );
199+ }
200+ if (numval == addr ) {
201+ while ((* nptr && !IS_SEPARATOR (* nptr ) && * nptr != 0x1b ) || (x86 && bits == 16 && colon && * nptr == ':' )) {
202+ nptr ++ ;
203+ }
204+ char * kwname = r_str_newf ("%s%s" , kw , name );
205+ if (kwname ) {
206+ char * numstr = r_str_ndup (ptr , nptr - ptr );
207+ if (numstr ) {
208+ hstr = r_str_replace (hstr , numstr , kwname , 0 );
209+ free (numstr );
210+ }
211+ free (kwname );
212+ }
213+ break ;
214+ }
215+ }
216+ return hstr ;
217+ }
218+ #endif
219+ return NULL ;
220+ }
0 commit comments