source: trunk/UMapFile.pas

Last change on this file was 2, checked in by george, 16 years ago

Přidáno: Ropracovaná verze 3.0

  • Property svn:executable set to *
File size: 6.3 KB
Line 
1{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2*
3* Unit Name : MapFile
4* Autor : Daniel Wischnewski
5* Copyright : Copyright © 2002 by gate(n)etwork. All Right Reserved.
6* Urheber : Daniel Wischnewski
7*
8* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
9
10unit UMapFile;
11
12interface
13
14uses
15 SysUtils, Classes, Windows, Dialogs;
16
17type
18 TMapFile = class
19 private
20 FMapFileName: String;
21 FSegmentData, FAdressData, FLineData: TStringList;
22 FMapFileBase: DWORD;
23 FExceptAddress: DWORD;
24 FExceptLineNumber: Integer;
25 FExceptMethodName: String;
26 FExceptUnitName: String;
27 FExceptionAnalyzed: Boolean;
28 procedure SetMapFileName(const Value: String);
29 procedure LoadMapFile;
30 protected
31 public
32 constructor Create;
33 destructor Destroy; override;
34
35 procedure LoadExceptionData(Address: Pointer = nil);
36
37 property MapFileName: String read FMapFileName write SetMapFileName;
38 property MapFileBase: DWORD read FMapFileBase write FMapFileBase;
39 property ExceptUnitName: String read FExceptUnitName;
40 property ExceptMethodName: String read FExceptMethodName;
41 property ExceptLineNumber: Integer read FExceptLineNumber;
42 property ExceptAddress: DWORD read FExceptAddress;
43 property ExceptionAnalyzed: Boolean read FExceptionAnalyzed;
44 end;
45
46implementation
47
48{ TMapFile }
49
50constructor TMapFile.Create;
51begin
52 inherited Create;
53 FSegmentData := TStringList.Create;
54 FAdressData := TStringList.Create;
55 FLineData := TStringList.Create;
56 FMapFileName := '';
57 FMapFileBase := $00401000;
58 FExceptAddress := 0;
59 FExceptLineNumber := 0;
60 FExceptMethodName := '';
61 FExceptUnitName := '';
62 FExceptionAnalyzed := False;
63end;
64
65destructor TMapFile.Destroy;
66begin
67 FreeAndNil(FSegmentData);
68 FreeAndNil(FAdressData);
69 FreeAndNil(FLineData);
70 inherited Destroy;
71end;
72
73procedure TMapFile.LoadExceptionData(Address: Pointer);
74var
75 UnitLineDataFound: Boolean;
76 I, J, LastLine: Integer;
77 Start, Stop, ProcAddr, LineAddr: DWORD;
78 Line: String;
79begin
80 // reset
81 FExceptAddress := 0;
82 FExceptLineNumber := 0;
83 FExceptMethodName := '';
84 FExceptUnitName := '';
85 FExceptionAnalyzed := False;
86
87 // load address
88 if Address = nil then
89 Address := ExceptAddr;
90 if Address = nil then
91 Exit;
92
93 // load and adjust exception address
94 FExceptAddress := DWORD(Address) - FMapFileBase;
95
96 // find unit of exception
97 I := 0;
98 while (I < FSegmentData.Count) and (FSegmentData[I] <> '') do
99 begin
100 try
101 // check whether address is within unit address limits
102 Start := DWORD(StrToInt('0x' + Copy(FSegmentData[I], 7, 8)));
103 Stop := Start + DWORD(StrToInt('0x' + Copy(FSegmentData[I], 16, 8)));
104 if (Start <= FExceptAddress) and (FExceptAddress < Stop) then
105 begin
106 Start := Pos('M=', FSegmentData[I]) + 2;
107 Stop := Pos('ACBP=', FSegmentData[I]);
108 if (Start > 0) and (Stop > 0) then
109 FExceptUnitName :=
110 Trim(Copy(FSegmentData[I], Start, Stop - Start - 1));
111 end;
112 except
113 end;
114 Inc(I);
115 end;
116
117 // find function of exception
118 I := 0;
119 while I < FAdressData.Count do
120 begin
121 try
122 ProcAddr := DWORD(StrToInt('0x' + Copy(FAdressData[I], 7, 8)));
123 if ProcAddr >= FExceptAddress then
124 begin
125 if ProcAddr = FExceptAddress then
126 Line := FAdressData[I]
127 else
128 Line := FAdressData[Pred(I)];
129 FExceptMethodName := Trim(Copy(Line, 22, Length(Line)));
130 Break;
131 end;
132 except
133 end;
134 Inc(I);
135 end;
136
137 // find line number of exception
138 I := 0;
139 UnitLineDataFound := False;
140 // search for unit section
141 while I < FLineData.Count do
142 begin
143 if Pos(FExceptUnitName, FLineData[I]) <> 0 then
144 begin
145 UnitLineDataFound := True;
146 Break;
147 end;
148 Inc(I);
149 end;
150 if UnitLineDataFound then
151 begin
152 // search for line number
153 LastLine := 0;
154 LineAddr := 0;
155 Inc(I, 2);
156 while I < FLineData.Count do
157 begin
158 //ShowMessage(FLineData[I]);
159 if Pos('Line numbers for', FLineData[I]) <> 0 then
160 Break;
161 if FLineData[I] <> '' then
162 try
163 for J := 0 to 3 do
164 begin
165 LineAddr := StrToInt('0x' + Copy(FLineData[I], J * 20 + 13, 8));
166 if LineAddr > FExceptAddress then
167 Break;
168 LastLine := StrToInt(Trim(Copy(FLineData[I], J * 20 + 1, 6)));
169 if LineAddr = FExceptAddress then
170 Break;
171 end;
172 except
173 end;
174 Inc(I);
175 end;
176 if LineAddr >= FExceptAddress then
177 FExceptLineNumber := LastLine;
178 end;
179
180 FExceptionAnalyzed := True;
181end;
182
183procedure TMapFile.LoadMapFile;
184var
185 I: Integer;
186begin
187 FSegmentData.Clear;
188 FAdressData.Clear;
189 FLineData.Clear;
190 if FileExists(FMapFileName) then
191 with TStringList.Create do
192 try
193 LoadFromFile(FMapFileName);
194 // find start of detailed segment block
195 I := 0;
196 while I < Count do
197 if Pos('Detailed map of segments', Strings[I]) <> 0 then
198 Break
199 else
200 Inc(I);
201 Inc(I, 2);
202
203 // copy all lines to segment data, until name-address block starts
204 while I < Count do
205 if Pos('Address Publics by Name', Strings[I]) <> 0 then
206 Break
207 else begin
208 FSegmentData.Add(Strings[I]);
209 Inc(I);
210 end;
211
212 // find start of value-address block
213 while I < Count do
214 if Pos('Address Publics by Value', Strings[I]) <> 0 then
215 Break
216 else
217 Inc(I);
218 Inc(I, 3);
219
220 // copy all lines to address data, until line number block starts
221 while I < Count do
222 if Pos('Line numbers for', Strings[I]) <> 0 then
223 Break
224 else begin
225 FAdressData.Add(Strings[I]);
226 Inc(I);
227 end;
228
229 // copy all remaining lines to line data
230 while I < Count do
231 begin
232 FLineData.Add(Strings[I]);
233 Inc(I);
234 end;
235 finally
236 Free;
237 end;
238end;
239
240procedure TMapFile.SetMapFileName(const Value: String);
241begin
242 if FMapFileName <> Value then
243 begin
244 FMapFileName := Value;
245 LoadMapFile;
246 end;
247end;
248
249end.
Note: See TracBrowser for help on using the repository browser.