1 /**
2 * @namespace biew
3 * @file codeguid.c
4 * @brief This file contains code navigation routines.
5 * @version -
6 * @remark this source file is part of Binary vIEW project (BIEW).
7 * The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
8 * All rights reserved. This software is redistributable under the
9 * licence given in the file "Licence.en" ("Licence.ru" in russian
10 * translation) distributed in the BIEW archive.
11 * @note Requires POSIX compatible development system
12 *
13 * @author Nickols_K
14 * @since 1995
15 * @note Development, fixes and improvements
16 * @author Kostya Nosov <k-nosov@yandex.ru>
17 * @date 12.09.2000
18 * @note removing difference keys for same locations of jump
19 **/
20 #include <string.h>
21 #include <stdio.h>
22 #include <limits.h>
23
24 #include "bmfile.h"
25 #include "biewutil.h"
26 #include "plugins/disasm.h"
27 #include "bconsole.h"
28 #include "codeguid.h"
29 #include "reg_form.h"
30 #include "biewlib/biewlib.h"
31 #include "biewlib/twin.h"
32 #include "biewlib/pmalloc.h"
33 #include "biewlib/kbd_code.h"
34
35 #define BACK_ADDR_SIZE 256
36 #define GO_ADDR_SIZE 37
37
38 static __filesize_t *BackAddr=NULL;
39 static int BackAddrPtr = -1;
40 static __filesize_t *GoAddr=NULL;
41 static unsigned int *GoLineNums=NULL;
42 static int GoAddrPtr = -1;
43 static unsigned char Alarm = 0;
44
45 extern int DisasmCurrLine;
46
47 char codeguid_image[] = "=>[X]";
48
initCodeGuider(void)49 tBool __FASTCALL__ initCodeGuider( void )
50 {
51 tBool ret = False;
52 BackAddr = PMalloc(sizeof(__filesize_t)*BACK_ADDR_SIZE);
53 if(BackAddr)
54 {
55 GoAddr = PMalloc(sizeof(__filesize_t)*GO_ADDR_SIZE);
56 if(!GoAddr) PFree(BackAddr);
57 else
58 {
59 GoLineNums = PMalloc(sizeof(unsigned int)*GO_ADDR_SIZE);
60 if(!GoLineNums) { PFree(BackAddr); PFree(GoAddr); }
61 else ret = True;
62 }
63 }
64 return ret;
65 }
66
termCodeGuider(void)67 void __FASTCALL__ termCodeGuider( void )
68 {
69 PFree(GoLineNums);
70 PFree(GoAddr);
71 PFree(BackAddr);
72 }
73
74 /*
75 Added by "Kostya Nosov" <k-nosov@yandex.ru>:
76 for removing difference keys for same locations of jump
77 */
78
gidGetAddressKey(unsigned index)79 static char __FASTCALL__ gidGetAddressKey( unsigned index )
80 {
81 int i,j;
82 char key;
83 tBool found;
84 __filesize_t addr1,addr2;
85 key = 0;
86 addr1 = GoAddr[index];
87 for (i = 0;i <= GoAddrPtr;i++)
88 {
89 addr2 = GoAddr[i];
90 if (addr2 == addr1) break;
91 /* check for presence addr2 above */
92 found = False;
93 for (j = 0;j < i;j++)
94 {
95 if (GoAddr[j] == addr2)
96 {
97 found = True;
98 break;
99 }
100 }
101 if (!found) key++;
102 }
103 return key < 10 ? key + '0' : key - 10 + 'A';
104 }
105
gidGetKeyIndex(char key)106 static int __FASTCALL__ gidGetKeyIndex( char key )
107 {
108 int res,i,j,index;
109 tBool found;
110 __filesize_t addr;
111 if (key > 'Z') key = key - 'z' + 'Z';
112 key = key > '9' ? key - 'A' + 10 : key - '0';
113 res = GoAddrPtr + 1;
114 index = 0;
115 for (i = 0;i <= GoAddrPtr;i++)
116 {
117 addr = GoAddr[i];
118 /* check for presence addr above */
119 found = False;
120 for (j = 0;j < i;j++)
121 {
122 if (GoAddr[j] == addr)
123 {
124 found = True;
125 break;
126 }
127 }
128 if (i > 0 && !found) index++;
129 if (index == key)
130 {
131 res = i;
132 break;
133 }
134 }
135 return res;
136 }
137
gidBuildKeyStr(void)138 static char * __NEAR__ __FASTCALL__ gidBuildKeyStr( void )
139 {
140 codeguid_image[3] = gidGetAddressKey(GoAddrPtr);
141 return codeguid_image;
142 }
143
GidResetGoAddress(int keycode)144 void __FASTCALL__ GidResetGoAddress( int keycode )
145 {
146 Alarm = 0;
147 if(keycode == KE_DOWNARROW)
148 {
149 int i;
150 if(GoAddrPtr >= 0)
151 {
152 if(GoLineNums[0] == 0)
153 {
154 memmove(GoAddr,&GoAddr[1],GoAddrPtr*sizeof(__filesize_t));
155 memmove(GoLineNums,&GoLineNums[1],GoAddrPtr*sizeof(unsigned int));
156 GoAddrPtr--;
157 }
158 for(i = 0;i <= GoAddrPtr;i++)
159 {
160 char dig;
161 GoLineNums[i]--;
162 dig = gidGetAddressKey(i);
163 twDirectWrite(twGetClientWidth(MainWnd)-1,GoLineNums[i]+2,&dig,1);
164 }
165 }
166 }
167 else if(keycode == KE_UPARROW)
168 {
169 int i;
170 Alarm = UCHAR_MAX;
171 if(GoAddrPtr >= 0)
172 {
173 for(i = 0;i <= GoAddrPtr;i++) GoLineNums[i]++;
174 if(GoLineNums[GoAddrPtr] >= twGetClientHeight(MainWnd)) GoAddrPtr--;
175 }
176 }
177 else GoAddrPtr = -1;
178 }
179
180 extern tBool DisasmPrepareMode;
181
GidAddGoAddress(char * str,__filesize_t addr)182 void __FASTCALL__ GidAddGoAddress(char *str,__filesize_t addr)
183 {
184 tAbsCoord width = twGetClientWidth(MainWnd);
185 unsigned bytecodes=activeDisasm->max_insn_len()*2;
186 int len,where;
187 if(DisasmPrepareMode) return;
188 len = strlen((char *)str);
189 where = (disPanelMode == PANMOD_FULL ? width :
190 disPanelMode == PANMOD_MEDIUM ? width-HA_LEN : width-(HA_LEN+1)-bytecodes) - 5;
191 if(Alarm)
192 {
193 int i;
194 if(GoAddrPtr < GO_ADDR_SIZE - 2) GoAddrPtr++;
195 memmove(&GoAddr[1],&GoAddr[0],GoAddrPtr*sizeof(long));
196 memmove(&GoLineNums[1],&GoLineNums[0],GoAddrPtr*sizeof(int));
197 GoAddr[0] = addr;
198 GoLineNums[0] = DisasmCurrLine;
199 if(len < where)
200 {
201 memset(&str[len],TWC_DEF_FILLER,where-len);
202 str[where] = 0;
203 }
204 strcat(str,codeguid_image);
205 str[where + 3] = '0';
206 for(i = 1;i <= GoAddrPtr;i++)
207 {
208 char dig;
209 dig = gidGetAddressKey(i);
210 twDirectWrite(width-1,GoLineNums[i]+1,&dig,1);
211 }
212 }
213 else
214 if(GoAddrPtr < GO_ADDR_SIZE - 2)
215 {
216 GoAddrPtr++;
217 GoAddr[GoAddrPtr] = addr;
218 GoLineNums[GoAddrPtr] = DisasmCurrLine;
219 if(len < where)
220 {
221 memset(&str[len],TWC_DEF_FILLER,where-len);
222 str[where] = 0;
223 }
224 strcpy((char *)&str[where],(char *)gidBuildKeyStr());
225 }
226 }
227
GidAddBackAddress(void)228 void __FASTCALL__ GidAddBackAddress( void )
229 {
230 if(BackAddrPtr >= BACK_ADDR_SIZE - 2)
231 {
232 memmove(BackAddr,&BackAddr[1],BackAddrPtr);
233 BackAddrPtr--;
234 }
235 BackAddrPtr++;
236 BackAddr[BackAddrPtr] = BMGetCurrFilePos();
237 }
238
GidGetGoAddress(unsigned keycode)239 __filesize_t __FASTCALL__ GidGetGoAddress(unsigned keycode)
240 {
241 __filesize_t ret;
242 if(keycode == KE_BKSPACE)
243 ret = BackAddrPtr >= 0 ? BackAddr[BackAddrPtr--] : BMGetCurrFilePos();
244 else
245 {
246 int ptr;
247 keycode &= 0x00FF;
248 ptr = gidGetKeyIndex(keycode);
249 if(ptr <= GoAddrPtr)
250 {
251 GidAddBackAddress();
252 ret = GoAddr[ptr];
253 }
254 else
255 ret = BMGetCurrFilePos();
256 }
257 return ret;
258 }
259
GidEncodeAddress(__filesize_t cfpos,tBool AddressDetail)260 char * __FASTCALL__ GidEncodeAddress(__filesize_t cfpos,tBool AddressDetail)
261 {
262 static char addr[11];
263 #if __WORDSIZE >= 32
264 strcpy(addr,((BMFileFlags&BMFF_USE64)?Get16Digit(cfpos):Get8Digit(cfpos)));
265 #else
266 strcpy(addr,Get8Digit(cfpos));
267 #endif
268 if(AddressDetail && detectedFormat->AddressResolving)
269 detectedFormat->AddressResolving(addr,cfpos);
270 strcat(addr,": ");
271 return addr;
272 }
273