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