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