1 /*
2 * HT Editor
3 * flt_analy.cc
4 *
5 * Copyright (C) 1999-2003 Sebastian Biallas (sb@biallas.net)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "analy.h"
22 #include "analy_alpha.h"
23 #include "analy_names.h"
24 #include "analy_ppc.h"
25 #include "analy_register.h"
26 #include "analy_x86.h"
27 #include "flt_analy.h"
28
29 #include "htctrl.h"
30 #include "htdebug.h"
31 #include "htiobox.h"
32 #include "htflt.h"
33 #include "strtools.h"
34 #include "pestruct.h"
35 #include "snprintf.h"
36 //#include "x86asm.h"
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 /*
43 *
44 */
init(ht_flt_shared_data * Flt_shared,File * File)45 void FLTAnalyser::init(ht_flt_shared_data *Flt_shared, File *File)
46 {
47 flt_shared = Flt_shared;
48 file = File;
49
50 validarea = new Area();
51 validarea->init();
52
53 Analyser::init();
54 }
55
beginAnalysis()56 void FLTAnalyser::beginAnalysis()
57 {
58 setLocationTreeOptimizeThreshold(100);
59 setSymbolTreeOptimizeThreshold(100);
60
61 /*
62 * give all sections a descriptive comment:
63 */
64
65 Address *secaddr;
66 secaddr = createAddress32(flt_shared->code_start);
67 if (validAddress(secaddr, scvalid)) {
68 addComment(secaddr, 0, "");
69 addComment(secaddr, 0, ";******************************************************************");
70 addComment(secaddr, 0, "; start of code");
71 addComment(secaddr, 0, ";******************************************************************");
72 }
73 delete secaddr;
74 secaddr = createAddress32(flt_shared->data_start);
75 if (validAddress(secaddr, scvalid)) {
76 addComment(secaddr, 0, "");
77 addComment(secaddr, 0, ";******************************************************************");
78 addComment(secaddr, 0, "; start of data");
79 addComment(secaddr, 0, ";******************************************************************");
80 }
81 delete secaddr;
82 secaddr = createAddress32(flt_shared->bss_start);
83 if (validAddress(secaddr, scvalid)) {
84 addComment(secaddr, 0, "");
85 addComment(secaddr, 0, ";******************************************************************");
86 addComment(secaddr, 0, "; start of bss");
87 addComment(secaddr, 0, ";******************************************************************");
88 }
89 delete secaddr;
90 Address *secaddr1, *secaddr2;
91 secaddr1 = createAddress32(flt_shared->code_start);
92 secaddr2 = createAddress32(flt_shared->bss_end);
93 validarea->add(secaddr1, secaddr2);
94 delete secaddr1;
95 delete secaddr2;
96
97 /*
98 * entrypoint
99 */
100
101 Address *entry;
102 entry = createAddress32(flt_shared->header.entry);
103 pushAddress(entry, entry);
104 assignSymbol(entry, "entrypoint", label_func);
105 addComment(entry, 0, "");
106 addComment(entry, 0, ";****************************");
107 addComment(entry, 0, "; entrypoint");
108 addComment(entry, 0, ";****************************");
109 delete entry;
110
111 setLocationTreeOptimizeThreshold(1000);
112 setSymbolTreeOptimizeThreshold(1000);
113
114 Analyser::beginAnalysis();
115 }
116
117 /*
118 *
119 */
load(ObjectStream & f)120 void FLTAnalyser::load(ObjectStream &f)
121 {
122 GET_OBJECT(f, validarea);
123 Analyser::load(f);
124 }
125
126 /*
127 *
128 */
done()129 void FLTAnalyser::done()
130 {
131 validarea->done();
132 delete validarea;
133 Analyser::done();
134 }
135
getObjectID() const136 ObjectID FLTAnalyser::getObjectID() const
137 {
138 return ATOM_FLT_ANALYSER;
139 }
140
141 /*
142 *
143 */
bufPtr(Address * Addr,byte * buf,int size)144 uint FLTAnalyser::bufPtr(Address *Addr, byte *buf, int size)
145 {
146 FileOfs ofs = addressToFileofs(Addr);
147 /* if (ofs == INVALID_FILE_OFS) {
148 int as = 1;
149 }*/
150 assert(ofs != INVALID_FILE_OFS);
151 file->seek(ofs);
152 return file->read(buf, size);
153 }
154
convertAddressToFLTAddress(Address * addr,FLTAddress * r)155 bool FLTAnalyser::convertAddressToFLTAddress(Address *addr, FLTAddress *r)
156 {
157 if (addr->getObjectID()==ATOM_ADDRESS_FLAT_32) {
158 *r = ((AddressFlat32*)addr)->addr;
159 return true;
160 } else {
161 return false;
162 }
163 }
164
createAddress()165 Address *FLTAnalyser::createAddress()
166 {
167 return new AddressFlat32();
168 }
169
createAddress32(uint32 addr)170 Address *FLTAnalyser::createAddress32(uint32 addr)
171 {
172 return new AddressFlat32(addr);
173 }
174
175 /*
176 *
177 */
createAssembler()178 Assembler *FLTAnalyser::createAssembler()
179 {
180 return NULL;
181 }
182
183 /*
184 *
185 */
addressToFileofs(Address * Addr)186 FileOfs FLTAnalyser::addressToFileofs(Address *Addr)
187 {
188 if (validAddress(Addr, scinitialized)) {
189 FLTAddress ea;
190 if (!convertAddressToFLTAddress(Addr, &ea)) return INVALID_FILE_OFS;
191 return (FileOfs)ea;
192 } else {
193 return INVALID_FILE_OFS;
194 }
195 }
196
197 /*
198 *
199 */
getSegmentNameByAddress(Address * Addr)200 const char *FLTAnalyser::getSegmentNameByAddress(Address *Addr)
201 {
202 FLTAddress ea;
203 if (!convertAddressToFLTAddress(Addr, &ea)) return NULL;
204 if (ea >= flt_shared->code_start) {
205 if (ea >= flt_shared->data_start) {
206 if (ea >= flt_shared->bss_start) {
207 if (ea >= flt_shared->bss_end) {
208 return NULL;
209 }
210 return "bss";
211 }
212 return "data";
213 }
214 return "code";
215 }
216 return NULL;
217 }
218
219 /*
220 *
221 */
getName(String & res)222 String &FLTAnalyser::getName(String &res)
223 {
224 return file->getDesc(res);
225 }
226
227 /*
228 *
229 */
getType()230 const char *FLTAnalyser::getType()
231 {
232 return "FLAT/Analyser";
233 }
234
235 /*
236 *
237 */
initCodeAnalyser()238 void FLTAnalyser::initCodeAnalyser()
239 {
240 Analyser::initCodeAnalyser();
241 }
242
243 /*
244 *
245 */
initUnasm()246 void FLTAnalyser::initUnasm()
247 {
248 DPRINTF("flt_analy: ");
249 // DPRINTF("initing analy_ppc_disassembler\n");
250 analy_disasm = NULL;
251 // ((AnalyPPCDisassembler*)analy_disasm)->init(this);
252 }
253
254 /*
255 *
256 */
log(const char * msg)257 void FLTAnalyser::log(const char *msg)
258 {
259 /*
260 * log() does to much traffic so dont log
261 * perhaps we reactivate this later
262 *
263 */
264 /* LOG(msg);*/
265 }
266
267 /*
268 *
269 */
nextValid(Address * Addr)270 Address *FLTAnalyser::nextValid(Address *Addr)
271 {
272 return (Address *)validarea->findNext(Addr);
273 }
274
275 /*
276 *
277 */
store(ObjectStream & f) const278 void FLTAnalyser::store(ObjectStream &f) const
279 {
280 PUT_OBJECT(f, validarea);
281 Analyser::store(f);
282 }
283
284 /*
285 *
286 */
queryConfig(int mode)287 int FLTAnalyser::queryConfig(int mode)
288 {
289 switch (mode) {
290 case Q_DO_ANALYSIS:
291 case Q_ENGAGE_CODE_ANALYSER:
292 case Q_ENGAGE_DATA_ANALYSER:
293 return true;
294 default:
295 return 0;
296 }
297 }
298
299 /*
300 *
301 */
fileofsToAddress(FileOfs fileofs)302 Address *FLTAnalyser::fileofsToAddress(FileOfs fileofs)
303 {
304 FLTAddress ea = (FLTAddress)fileofs;
305 if (ea >= flt_shared->code_start && ea < flt_shared->data_end) {
306 return createAddress32(ea);
307 } else {
308 return new InvalidAddress();
309 }
310 }
311
312 /*
313 *
314 */
validAddress(Address * Addr,tsectype action)315 bool FLTAnalyser::validAddress(Address *Addr, tsectype action)
316 {
317 FLTAddress ea;
318 if (!convertAddressToFLTAddress(Addr, &ea)) return false;
319 if (ea >= flt_shared->code_start) {
320 if (ea >= flt_shared->data_start) {
321 if (ea >= flt_shared->bss_start) {
322 if (ea >= flt_shared->bss_end) {
323 return false;
324 }
325 switch (action) {
326 case scvalid:
327 case scread:
328 case scwrite:
329 case screadwrite:
330 return true;
331 case sccode:
332 case scinitialized:
333 return false;
334 }
335 }
336 switch (action) {
337 case scvalid:
338 case scread:
339 case scwrite:
340 case screadwrite:
341 case scinitialized:
342 return true;
343 case sccode:
344 return false;
345 }
346 }
347 switch (action) {
348 case scvalid:
349 case scread:
350 case scinitialized:
351 return true;
352 case scwrite:
353 case screadwrite:
354 case sccode:
355 return false;
356 }
357 }
358 return false;
359 }
360
361
362