]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c
MdeModulePkg: Fix GCC build failure
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbSymbol.c
CommitLineData
748edcd5
PB
1/*++\r
2\r
eebfb7b2 3Copyright (c) 2007 - 2016, Intel Corporation\r
748edcd5
PB
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 EdbSymbol.c\r
15\r
16Abstract:\r
17\r
18\r
19--*/\r
20\r
21#include "Edb.h"\r
22\r
23EFI_STATUS\r
24EdbLoadSymbolSingleEntry (\r
25 IN EFI_DEBUGGER_SYMBOL_OBJECT *Object,\r
26 IN CHAR8 *Name,\r
27 IN CHAR8 *ObjName,\r
28 IN UINTN Address,\r
29 IN EFI_DEBUGGER_SYMBOL_TYPE Type\r
30 )\r
31/*++\r
32\r
33Routine Description:\r
34\r
35 Load single symbol entry\r
36\r
37Arguments:\r
38\r
39 Object - Symbol file object\r
40 Name - Symbol name\r
41 ObjName - Object name\r
42 Address - Symbol address\r
43 Type - Symbol type\r
44\r
45Returns:\r
46\r
47 EFI_SUCCESS - add single symbol entry successfully\r
48\r
49--*/\r
50{\r
51 EFI_DEBUGGER_SYMBOL_ENTRY *Entry;\r
52\r
53 //\r
54 // Check Count VS MaxCount\r
55 //\r
56 if (Object->EntryCount >= Object->MaxEntryCount) {\r
57 //\r
58 // reallocate (for codebuffer too)\r
59 // TBD\r
60 //\r
61 return EFI_OUT_OF_RESOURCES;\r
62 }\r
63\r
64 Entry = &Object->Entry[Object->EntryCount];\r
65\r
66 //\r
67 // Print Debug info\r
68 //\r
69 if (sizeof (UINTN) == sizeof(UINT64)) {\r
70 DEBUG ((DEBUG_ERROR, " Symbol: %a, Address: 0x%016lx (%d)\n", Name, (UINT64)Address, (UINTN)Type));\r
71 } else {\r
72 DEBUG ((DEBUG_ERROR, " Symbol: %a, Address: 0x%08x (%d)\n", Name, Address, (UINTN)Type));\r
73 }\r
74\r
75 //\r
76 // Fill the entry - name, RVA, type\r
77 //\r
78 AsciiStrnCpyS (Entry->Name, sizeof(Entry->Name), Name, sizeof(Entry->Name) - 1);\r
79 if (ObjName != NULL) {\r
80 AsciiStrnCpyS (Entry->ObjName, sizeof(Entry->ObjName), ObjName, sizeof(Entry->ObjName) - 1);\r
81 }\r
82 Entry->RVA = Address % EFI_DEBUGGER_DEFAULT_LINK_IMAGEBASE;\r
83 Entry->Type = Type;\r
84\r
85 //\r
86 // Increase Count\r
87 //\r
88 Object->EntryCount++;\r
89\r
90 //\r
91 // Done\r
92 //\r
93 return EFI_SUCCESS;\r
94}\r
95\r
96typedef enum {\r
97 EdbEbcMapParseStateUninitialized,\r
98 EdbEbcMapParseStateSymbolStart,\r
99 EdbEbcMapParseStateSeHandlerSymbol,\r
100 EdbEbcMapParseStateFunctionSymbol,\r
101 EdbEbcMapParseStateVarbssInitSymbol,\r
102 EdbEbcMapParseStateCrtSymbol,\r
103 EdbEbcMapParseStateVariableSymbol,\r
104 EdbEbcMapParseStateStaticFunctionSymbol,\r
105 EdbEbcMapParseStateMax,\r
106} EDB_EBC_MAP_PARSE_STATE;\r
107\r
108typedef enum {\r
109 EdbEbcSymbolParseStateUninitialized,\r
110 EdbEbcSymbolParseStateReadyForName,\r
111 EdbEbcSymbolParseStateReadyForRVA,\r
112 EdbEbcSymbolParseStateReadyForType,\r
113 EdbEbcSymbolParseStateReadyForObject,\r
114 EdbEbcSymbolParseStateMax,\r
115} EDB_EBC_SYMBOL_PARSE_STATE;\r
116\r
117/*++\r
118\r
119 The following code depends on the MAP file generated by IEC compiler (actually Microsoft linker).\r
120\r
121 Sample as follows: EbcTest.map\r
122===============================================================================\r
123 EbcTest\r
124\r
125 Timestamp is 45b02718 (Fri Jan 19 10:04:08 2007)\r
126\r
127 Preferred load address is 10000000\r
128\r
129 Start Length Name Class\r
130 0001:00000000 00000370H .text CODE\r
131 0002:00000000 00000030H _VARBSS_INIT CODE\r
132 0003:00000000 00000004H .CRT$TSA DATA\r
133 0003:00000004 00000004H .CRT$TSC DATA\r
134 0003:00000008 00000004H .CRT$X DATA\r
135 0003:0000000c 00000008H .CRT$XCU DATA\r
136 0003:00000014 00000004H .CRT$Z DATA\r
137 0003:00000020 0000001cH .rdata DATA\r
138 0003:0000003c 00000000H .edata DATA\r
139 0003:0000003c 00000056H .rdata$debug DATA\r
140 0004:00000000 00000070H .data DATA\r
141 0004:00000070 00000020H .bss DATA\r
142\r
143 Address Publics by Value Rva+Base Lib:Object\r
144\r
145 0000:00000000 ___safe_se_handler_table 00000000 <absolute>\r
146 0000:00000000 ___safe_se_handler_count 00000000 <absolute>\r
147 0001:00000042 TestSubRoutine 10000442 f EbcTest.obj\r
148 0001:0000011a EfiMain 1000051a f EbcTest.obj\r
149 0001:00000200 TestSubRoutineSub 10000600 f EbcTestSub.obj\r
150 0001:00000220 EfiStart 10000620 f EbcLib:EbcLib.obj\r
151 0002:00000000 varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest$c45b02717 10000800 f EbcTest.obj\r
152 0002:00000020 varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTestSub$c45af77f3 10000820 f EbcTestSub.obj\r
153 0003:00000000 CrtThunkBegin 10000a00 EbcLib:EbcLib.obj\r
154 0003:00000004 CrtThunkEnd 10000a04 EbcLib:EbcLib.obj\r
155 0003:00000008 CrtBegin 10000a08 EbcLib:EbcLib.obj\r
156 0003:00000014 CrtEnd 10000a14 EbcLib:EbcLib.obj\r
157 0004:00000070 TestStr 10000c70 EbcTest.obj\r
158 0004:00000078 TestVariable1 10000c78 EbcTest.obj\r
159 0004:00000080 TestSubVariableSub 10000c80 EbcTestSub.obj\r
160\r
161 entry point at 0001:00000220\r
162\r
163 Static symbols\r
164\r
165 0001:00000000 TestSubRoutine2 10000400 f EbcTest.obj\r
166===============================================================================\r
167\r
168--*/\r
169EFI_STATUS\r
170EdbLoadSymbolEntryByIec (\r
171 IN EFI_DEBUGGER_SYMBOL_OBJECT *Object,\r
172 IN UINTN BufferSize,\r
173 IN VOID *Buffer\r
174 )\r
175/*++\r
176\r
177Routine Description:\r
178\r
179 Load symbol entry by Iec\r
180\r
181Arguments:\r
182\r
183 DebuggerPrivate - EBC Debugger private data structure\r
184 Object - Symbol file object\r
185 BufferSize - Symbol file buffer size\r
186 Buffer - Symbol file buffer\r
187\r
188Returns:\r
189\r
190 EFI_SUCCESS - add symbol entry successfully\r
191\r
192--*/\r
193{\r
194 CHAR8 *LineBuffer;\r
195 CHAR8 *FieldBuffer;\r
748edcd5
PB
196 EDB_EBC_MAP_PARSE_STATE MapParseState;\r
197 EDB_EBC_SYMBOL_PARSE_STATE SymbolParseState;\r
198 CHAR8 *Name;\r
199 CHAR8 *ObjName;\r
200 UINTN Address;\r
201 EFI_DEBUGGER_SYMBOL_TYPE Type;\r
202\r
748edcd5
PB
203\r
204 //\r
205 // Begin to parse the Buffer\r
206 //\r
207 LineBuffer = AsciiStrGetNewTokenLine (Buffer, "\n\r");\r
208 MapParseState = EdbEbcMapParseStateUninitialized;\r
209 //\r
210 // Check each line\r
211 //\r
212 while (LineBuffer != NULL) {\r
213 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, " ");\r
214 SymbolParseState = EdbEbcSymbolParseStateUninitialized;\r
215 //\r
216 // Init entry value\r
217 //\r
218 Name = NULL;\r
219 ObjName = NULL;\r
220 Address = 0;\r
221 Type = EfiDebuggerSymbolTypeMax;\r
222 //\r
223 // Check each field\r
224 //\r
225 while (FieldBuffer != NULL) {\r
226 if (AsciiStrCmp (FieldBuffer, "") == 0) {\r
227 FieldBuffer = AsciiStrGetNextTokenField (" ");\r
228 continue;\r
229 }\r
230 //\r
231 // check "Address"\r
232 //\r
233 if (AsciiStrCmp (FieldBuffer, "Address") == 0) {\r
234 MapParseState = EdbEbcMapParseStateSymbolStart;\r
235 break;\r
236 }\r
237 //\r
238 // check "Static"\r
239 //\r
240 if (AsciiStrCmp (FieldBuffer, "Static") == 0) {\r
241 MapParseState = EdbEbcMapParseStateStaticFunctionSymbol;\r
242 break;\r
243 }\r
244\r
245 if (MapParseState == EdbEbcMapParseStateUninitialized) {\r
246 //\r
247 // Do not parse anything until get "Address" or "Static"\r
248 //\r
249 break;\r
250 }\r
251 if (AsciiStrCmp (FieldBuffer, "entry") == 0) {\r
252 //\r
253 // Skip entry point\r
254 //\r
255 break;\r
256 }\r
257\r
258 //\r
259 // Now we start to parse this line for Name, Address, and Object\r
260 //\r
261 switch (SymbolParseState) {\r
262 case EdbEbcSymbolParseStateUninitialized:\r
263 //\r
264 // Get the Address\r
265 //\r
266 SymbolParseState = EdbEbcSymbolParseStateReadyForName;\r
267 break;\r
268 case EdbEbcSymbolParseStateReadyForName:\r
269 //\r
270 // Get the Name\r
271 //\r
272 if (AsciiStrnCmp (FieldBuffer, "___safe_se_handler", AsciiStrLen ("___safe_se_handler")) == 0) {\r
273 //\r
274 // skip SeHandler\r
275 //\r
276 MapParseState = EdbEbcMapParseStateSeHandlerSymbol;\r
277 goto ExitFieldParse;\r
278 } else if (AsciiStrnCmp (FieldBuffer, "varbss_init", AsciiStrLen ("varbss_init")) == 0) {\r
279 //\r
280 // check VarbssInit\r
281 //\r
282 MapParseState = EdbEbcMapParseStateVarbssInitSymbol;\r
283// goto ExitFieldParse;\r
284 Name = FieldBuffer;\r
285 SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;\r
286 } else if (AsciiStrnCmp (FieldBuffer, "Crt", AsciiStrLen ("Crt")) == 0) {\r
287 //\r
288 // check Crt\r
289 //\r
290 MapParseState = EdbEbcMapParseStateCrtSymbol;\r
291// goto ExitFieldParse;\r
292 Name = FieldBuffer;\r
293 SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;\r
294 } else {\r
295 //\r
296 // Now, it is normal function\r
297 //\r
298 switch (MapParseState) {\r
299 case EdbEbcMapParseStateSeHandlerSymbol:\r
300 MapParseState = EdbEbcMapParseStateFunctionSymbol;\r
301 break;\r
302 case EdbEbcMapParseStateCrtSymbol:\r
303 MapParseState = EdbEbcMapParseStateVariableSymbol;\r
304 break;\r
305 case EdbEbcMapParseStateFunctionSymbol:\r
306 case EdbEbcMapParseStateVariableSymbol:\r
307 case EdbEbcMapParseStateStaticFunctionSymbol:\r
308 break;\r
309 default:\r
310 ASSERT (FALSE);\r
311 break;\r
312 }\r
313 Name = FieldBuffer;\r
314 SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;\r
315 }\r
316 break;\r
317 case EdbEbcSymbolParseStateReadyForRVA:\r
318 //\r
319 // Get the RVA\r
320 //\r
321 Address = AsciiXtoi (FieldBuffer);\r
322 SymbolParseState = EdbEbcSymbolParseStateReadyForType;\r
323 break;\r
324 case EdbEbcSymbolParseStateReadyForType:\r
325 //\r
326 // Get the Type. This is optional, only for "f".\r
327 //\r
328 if (AsciiStrCmp (FieldBuffer, "f") == 0) {\r
329 SymbolParseState = EdbEbcSymbolParseStateReadyForObject;\r
330 switch (MapParseState) {\r
331 case EdbEbcMapParseStateFunctionSymbol:\r
332 case EdbEbcMapParseStateVarbssInitSymbol:\r
333 Type = EfiDebuggerSymbolFunction;\r
334 break;\r
335 case EdbEbcMapParseStateStaticFunctionSymbol:\r
336 Type = EfiDebuggerSymbolStaticFunction;\r
337 break;\r
338 default:\r
339 ASSERT (FALSE);\r
340 break;\r
341 }\r
342 break;\r
343 }\r
344 //\r
345 // Else it should be Object.\r
346 // let it bypass here\r
347 //\r
348 case EdbEbcSymbolParseStateReadyForObject:\r
349 switch (Type) {\r
350 case EfiDebuggerSymbolTypeMax:\r
351 switch (MapParseState) {\r
352 case EdbEbcMapParseStateVariableSymbol:\r
353 case EdbEbcMapParseStateCrtSymbol:\r
354 Type = EfiDebuggerSymbolGlobalVariable;\r
355 break;\r
356 case EdbEbcMapParseStateSeHandlerSymbol:\r
357 //\r
358 // do nothing here\r
359 //\r
360 break;\r
361 default:\r
362 ASSERT (FALSE);\r
363 break;\r
364 }\r
365 break;\r
366 case EfiDebuggerSymbolFunction:\r
367 case EfiDebuggerSymbolStaticFunction:\r
368 break;\r
369 default:\r
370 ASSERT (FALSE);\r
371 break;\r
372 }\r
373 //\r
374 // Get the Object\r
375 //\r
376 ObjName = FieldBuffer;\r
377 SymbolParseState = EdbEbcSymbolParseStateUninitialized;\r
378 break;\r
379 default:\r
380 ASSERT (FALSE);\r
381 break;\r
382 }\r
383\r
384 //\r
385 // Get the next field\r
386 //\r
387 FieldBuffer = AsciiStrGetNextTokenField (" ");\r
388 }\r
389\r
390 //\r
391 // Add the entry if we get everything.\r
392 //\r
393 if ((Name != NULL) && (Type != EfiDebuggerSymbolTypeMax)) {\r
394 EdbLoadSymbolSingleEntry (Object, Name, ObjName, Address, Type);\r
395 }\r
396\r
397ExitFieldParse:\r
398 //\r
399 // Get the next line\r
400 //\r
401 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");\r
402 }\r
403\r
404 //\r
405 // Done\r
406 //\r
407 return EFI_SUCCESS;\r
408}\r
409\r
410EFI_STATUS\r
411EdbLoadSymbolEntry (\r
412 IN EFI_DEBUGGER_SYMBOL_OBJECT *Object,\r
413 IN UINTN BufferSize,\r
414 IN VOID *Buffer\r
415 )\r
416/*++\r
417\r
418Routine Description:\r
419\r
420 Load symbol entry\r
421\r
422Arguments:\r
423\r
424 Object - Symbol file object\r
425 BufferSize - Symbol file buffer size\r
426 Buffer - Symbol file buffer\r
427\r
428Returns:\r
429\r
430 EFI_SUCCESS - add symbol entry successfully\r
431\r
432--*/\r
433{\r
434 //\r
435 // MAP file format depends on the compiler (actually linker).\r
436 //\r
437 // It is possible to check the different MAP file format in this routine.\r
438 // Now only IEC is supported.\r
439 //\r
440 return EdbLoadSymbolEntryByIec (Object, BufferSize, Buffer);\r
441}\r
442\r
443EFI_DEBUGGER_SYMBOL_OBJECT *\r
444EdbFindSymbolFile (\r
445 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
446 IN CHAR16 *FileName,\r
447 IN OUT UINTN *Index OPTIONAL\r
448 )\r
449/*++\r
450\r
451Routine Description:\r
452\r
453 Find symbol file by name\r
454\r
455Arguments:\r
456\r
457 DebuggerPrivate - EBC Debugger private data structure\r
458 FileName - Symbol file name\r
459 Index - Symbol file index\r
460\r
461Returns:\r
462\r
463 Object\r
464\r
465--*/\r
466{\r
467 UINTN ObjectIndex;\r
468\r
469 //\r
470 // Check each Object\r
471 //\r
472 for (ObjectIndex = 0; ObjectIndex < DebuggerPrivate->DebuggerSymbolContext.ObjectCount; ObjectIndex++) {\r
473 if (StrCmp (FileName, DebuggerPrivate->DebuggerSymbolContext.Object[ObjectIndex].Name) == 0) {\r
474 //\r
475 // Name match, found it\r
476 //\r
477 if (Index != NULL) {\r
478 *Index = ObjectIndex;\r
479 }\r
480 return &DebuggerPrivate->DebuggerSymbolContext.Object[ObjectIndex];\r
481 }\r
482 }\r
483\r
484 //\r
485 // Not found\r
486 //\r
487 return NULL;\r
488}\r
489\r
490UINTN\r
491EbdFindSymbolAddress (\r
492 IN UINTN Address,\r
493 IN EDB_MATCH_SYMBOL_TYPE Type,\r
494 OUT EFI_DEBUGGER_SYMBOL_OBJECT **RetObject,\r
495 OUT EFI_DEBUGGER_SYMBOL_ENTRY **RetEntry\r
496 )\r
497/*++\r
498\r
499Routine Description:\r
500\r
501 Find symbol by address\r
502\r
503Arguments:\r
504\r
505 Address - Symbol address\r
506 Type - Search type\r
507 RetObject - Symbol object\r
508 RetEntry - Symbol entry\r
509\r
510Returns:\r
511\r
512 Nearest symbol address\r
513\r
514--*/\r
515{\r
516 UINTN Index;\r
517 UINTN SubIndex;\r
518 UINTN CandidateLowerAddress;\r
519 UINTN CandidateUpperAddress;\r
520 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
521 EFI_DEBUGGER_SYMBOL_ENTRY *Entry;\r
522 EFI_DEBUGGER_SYMBOL_ENTRY *LowEntry;\r
523 EFI_DEBUGGER_SYMBOL_ENTRY *UpperEntry;\r
524 EFI_DEBUGGER_SYMBOL_OBJECT *LowObject;\r
525 EFI_DEBUGGER_SYMBOL_OBJECT *UpperObject;\r
526\r
527 if ((Type < 0) || (Type >= EdbMatchSymbolTypeMax)) {\r
528 return 0;\r
529 }\r
530\r
531 //\r
532 // Init\r
533 //\r
534 CandidateLowerAddress = 0;\r
535 CandidateUpperAddress = (UINTN)-1;\r
536 LowEntry = NULL;\r
537 UpperEntry = NULL;\r
538 LowObject = NULL;\r
539 UpperObject = NULL;\r
540\r
541 //\r
542 // Go through each object\r
543 //\r
544 Object = mDebuggerPrivate.DebuggerSymbolContext.Object;\r
545 for (Index = 0; Index < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; Index++, Object++) {\r
546 if (Object->EntryCount == 0) {\r
547 continue;\r
548 }\r
549 //\r
550 // Go through each entry\r
551 //\r
552 Entry = Object->Entry;\r
553 for (SubIndex = 0; SubIndex < Object->EntryCount; SubIndex++, Entry++) {\r
554 if (Address != Entry->RVA + Object->BaseAddress) {\r
555 //\r
556 // Check for nearest address\r
557 //\r
558 if (Address > Entry->RVA + Object->BaseAddress) {\r
559 //\r
560 // Record it if Current RVA < Address\r
561 //\r
562 if (CandidateLowerAddress < Entry->RVA + Object->BaseAddress) {\r
563 CandidateLowerAddress = Entry->RVA + Object->BaseAddress;\r
564 LowEntry = Entry;\r
565 LowObject = Object;\r
566 }\r
567 } else {\r
568 //\r
569 // Record it if Current RVA > Address\r
570 //\r
571 if (CandidateUpperAddress > Entry->RVA + Object->BaseAddress) {\r
572 CandidateUpperAddress = Entry->RVA + Object->BaseAddress;\r
573 UpperEntry = Entry;\r
574 UpperObject = Object;\r
575 }\r
576 }\r
577 continue;\r
578 }\r
579 //\r
580 // address match, return directly\r
581 //\r
582 *RetEntry = Entry;\r
583 *RetObject = Object;\r
584 return Address;\r
585 }\r
586 }\r
587\r
588 //\r
589 // No Match, provide latest symbol\r
590 //\r
591\r
592 if ((Address - CandidateLowerAddress) < EFI_DEBUGGER_MAX_SYMBOL_ADDRESS_DELTA_VALUE) {\r
593 //\r
594 // Check for lower address\r
595 //\r
596 if (((Type == EdbMatchSymbolTypeNearestAddress) &&\r
597 ((CandidateUpperAddress - Address) > (Address - CandidateLowerAddress))) ||\r
598 (Type == EdbMatchSymbolTypeLowerAddress)) {\r
599 //\r
600 // return nearest lower address\r
601 //\r
602 *RetEntry = LowEntry;\r
603 *RetObject = LowObject;\r
604 return CandidateLowerAddress;\r
605 }\r
606 }\r
607\r
608 if ((CandidateUpperAddress - Address) < EFI_DEBUGGER_MAX_SYMBOL_ADDRESS_DELTA_VALUE) {\r
609 //\r
610 // Check for upper address\r
611 //\r
612 if (((Type == EdbMatchSymbolTypeNearestAddress) &&\r
613 ((CandidateUpperAddress - Address) < (Address - CandidateLowerAddress))) ||\r
614 (Type == EdbMatchSymbolTypeUpperAddress)) {\r
615 //\r
616 // return nearest upper address\r
617 //\r
618 *RetEntry = UpperEntry;\r
619 *RetObject = UpperObject;\r
620 return CandidateUpperAddress;\r
621 }\r
622 }\r
623\r
624 //\r
625 // No match and nearest one, return NULL\r
626 //\r
627 return 0;\r
628}\r
629\r
630EFI_STATUS\r
631EdbUnloadSymbol (\r
632 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
633 IN CHAR16 *FileName\r
634 )\r
635/*++\r
636\r
637Routine Description:\r
638\r
639 Unload symbol file by name\r
640\r
641Arguments:\r
642\r
643 DebuggerPrivate - EBC Debugger private data structure\r
644 FileName - Symbol file name\r
645\r
646Returns:\r
647\r
648 EFI_SUCCESS - unload symbol successfully\r
649\r
650--*/\r
651{\r
652 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
653 UINTN ObjectIndex;\r
654 UINTN Index;\r
655 EFI_DEBUGGER_SYMBOL_ENTRY *OldEntry;\r
656 UINTN OldEntryCount;\r
657 UINTN MaxEntryCount;\r
658 VOID **OldSourceBuffer;\r
659\r
660 //\r
661 // Find Symbol\r
662 //\r
663 Object = EdbFindSymbolFile (DebuggerPrivate, FileName, &ObjectIndex);\r
664 if (Object == NULL) {\r
665 EDBPrint (L"SymbolFile is not loaded!\n");\r
666 return EFI_DEBUG_CONTINUE;\r
667 }\r
668\r
669 //\r
670 // Record old data\r
671 //\r
672 Object = DebuggerPrivate->DebuggerSymbolContext.Object;\r
673 OldEntry = Object->Entry;\r
674 OldSourceBuffer = Object->SourceBuffer;\r
675 MaxEntryCount = Object->MaxEntryCount;\r
676 OldEntryCount = Object->EntryCount;\r
677\r
678 //\r
679 // Remove the matched Object\r
680 //\r
681 for (Index = ObjectIndex; Index < DebuggerPrivate->DebuggerSymbolContext.ObjectCount - 1; Index++) {\r
682 CopyMem (&Object[Index], &Object[Index + 1], sizeof(EFI_DEBUGGER_SYMBOL_OBJECT));\r
683 }\r
684 ZeroMem (&Object[Index], sizeof(Object[Index]));\r
685\r
686 //\r
687 // Move old data to new place\r
688 //\r
689 Object[Index].Entry = OldEntry;\r
690 Object[Index].SourceBuffer = OldSourceBuffer;\r
691 Object[Index].MaxEntryCount = MaxEntryCount;\r
692 DebuggerPrivate->DebuggerSymbolContext.ObjectCount --;\r
693\r
694 //\r
695 // Clean old entry data\r
696 //\r
697 for (Index = 0; Index < OldEntryCount; Index++) {\r
698 ZeroMem (&OldEntry[Index], sizeof(OldEntry[Index]));\r
699 }\r
700\r
701 //\r
702 // Free OldSourceBuffer\r
703 //\r
704 for (Index = 0; OldSourceBuffer[Index] != NULL; Index++) {\r
705 gBS->FreePool (OldSourceBuffer[Index]);\r
706 OldSourceBuffer[Index] = NULL;\r
707 }\r
708\r
709 return EFI_SUCCESS;\r
710}\r
711\r
712EFI_STATUS\r
713EdbLoadSymbol (\r
714 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
715 IN CHAR16 *FileName,\r
716 IN UINTN BufferSize,\r
717 IN VOID *Buffer\r
718 )\r
719/*++\r
720\r
721Routine Description:\r
722\r
723 Load symbol file by name\r
724\r
725Arguments:\r
726\r
727 DebuggerPrivate - EBC Debugger private data structure\r
728 FileName - Symbol file name\r
729 BufferSize - Symbol file buffer size\r
730 Buffer - Symbol file buffer\r
731\r
732Returns:\r
733\r
734 EFI_SUCCESS - load symbol successfully\r
735\r
736--*/\r
737{\r
738 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
739 EFI_STATUS Status;\r
740\r
741 //\r
742 // Check duplicated File\r
743 //\r
744 Object = EdbFindSymbolFile (DebuggerPrivate, FileName, NULL);\r
745 if (Object != NULL) {\r
746 Status = EdbUnloadSymbol (DebuggerPrivate, FileName);\r
747 if (EFI_ERROR(Status)) {\r
748 DEBUG ((DEBUG_ERROR, "Unload Duplicated Symbol File Error!\n"));\r
749 return Status;\r
750 }\r
751 }\r
752\r
753 //\r
754 // Check Count VS MaxCount\r
755 //\r
756 if (DebuggerPrivate->DebuggerSymbolContext.ObjectCount >= DebuggerPrivate->DebuggerSymbolContext.MaxObjectCount) {\r
757 //\r
758 // reallocate\r
759 // TBD\r
760 //\r
761 return EFI_OUT_OF_RESOURCES;\r
762 }\r
763\r
764 Object = &DebuggerPrivate->DebuggerSymbolContext.Object[DebuggerPrivate->DebuggerSymbolContext.ObjectCount];\r
765\r
766 //\r
767 // Init Object\r
768 //\r
769 Object->EntryCount = 0;\r
770 Object->MaxEntryCount = EFI_DEBUGGER_SYMBOL_ENTRY_MAX;\r
771\r
772 //\r
773 // Load SymbolEntry\r
774 //\r
775 DEBUG ((DEBUG_ERROR, "Symbol File: %s\n", FileName));\r
776 Status = EdbLoadSymbolEntry (Object, BufferSize, Buffer);\r
777 if (EFI_ERROR (Status)) {\r
778 return Status;\r
779 }\r
780\r
781 //\r
782 // Fill Object value\r
783 //\r
784 StrnCpyS (Object->Name, sizeof(Object->Name) / sizeof(CHAR16),\r
785 FileName, (sizeof(Object->Name) / sizeof(CHAR16)) - 1);\r
786 Object->BaseAddress = 0;\r
787\r
788 //\r
789 // Increase the object count\r
790 //\r
791 DebuggerPrivate->DebuggerSymbolContext.ObjectCount ++;\r
792\r
793 return EFI_SUCCESS;\r
794}\r
795\r
796CHAR8 *\r
797GetPdbPath (\r
798 VOID *ImageBase\r
799 )\r
800/*++\r
801\r
802Routine Description:\r
803\r
804 Located PDB path name in PE image\r
805\r
806Arguments:\r
807\r
808 ImageBase - base of PE to search\r
809\r
810Returns:\r
811\r
812 Pointer into image at offset of PDB file name if PDB file name is found,\r
813 Otherwise a pointer to an empty string.\r
814\r
815--*/\r
816{\r
817 CHAR8 *PdbPath;\r
818 UINT32 DirCount;\r
819 EFI_IMAGE_DOS_HEADER *DosHdr;\r
820 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
821 EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHdr32;\r
822 EFI_IMAGE_OPTIONAL_HEADER64 *OptionalHdr64;\r
823 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
824 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
825 VOID *CodeViewEntryPointer;\r
826\r
827 //\r
828 // Init value\r
829 //\r
830 CodeViewEntryPointer = NULL;\r
831 PdbPath = NULL;\r
832 DosHdr = ImageBase;\r
833\r
834 //\r
835 // Check magic\r
836 //\r
837 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
838 return NULL;\r
839 }\r
840 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) DosHdr + DosHdr->e_lfanew);\r
841 //\r
842 // Check Machine, filter for EBC\r
843 //\r
844 if (NtHdr->Pe32.FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {\r
845 //\r
846 // If not EBC, return NULL\r
847 //\r
848 return NULL;\r
849 }\r
850\r
851 //\r
852 // Get DirectoryEntry\r
853 // EBC spec says PE32+, but implementation uses PE32. So check dynamically here.\r
854 //\r
855 if (NtHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
856 OptionalHdr32 = (VOID *) &NtHdr->Pe32.OptionalHeader;\r
857 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
858 } else if (NtHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
859 OptionalHdr64 = (VOID *) &NtHdr->Pe32Plus.OptionalHeader;\r
860 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
861 } else {\r
862 return NULL;\r
863 }\r
864 if (DirectoryEntry->VirtualAddress == 0) {\r
865 return NULL;\r
866 }\r
867 //\r
868 // Go through DirectoryEntry\r
869 //\r
870 for (DirCount = 0;\r
871 (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;\r
872 DirCount++\r
873 ) {\r
874 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
875 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
876 //\r
877 // Match DebugEntry, only CODEVIEW_SIGNATURE_NB10 and CODEVIEW_SIGNATURE_RSDS are supported.\r
878 //\r
879 CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase);\r
880 switch (*(UINT32 *) CodeViewEntryPointer) {\r
881 case CODEVIEW_SIGNATURE_NB10:\r
882 PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
883 break;\r
884 case CODEVIEW_SIGNATURE_RSDS:\r
885 PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
886 break;\r
887 default:\r
888 break;\r
889 }\r
890 }\r
891 }\r
892\r
893 //\r
894 // Done successfully\r
895 //\r
896 return PdbPath;\r
897}\r
898\r
899BOOLEAN\r
900MatchPdbAndMap (\r
901 IN CHAR8 *PdbFileName,\r
902 IN CHAR16 *MapFileName\r
903 )\r
904/*++\r
905\r
906Routine Description:\r
907\r
908 Check whether PDB file and MAP file have same name\r
909\r
910Arguments:\r
911\r
912 PdbFileName - PDB file name\r
913 MapFileName - MAP file name\r
914\r
915Returns:\r
916\r
917 TRUE - PDB and MAP file name match\r
918 FALSE - PDB and MAP file name not match\r
919\r
920--*/\r
921{\r
922 UINTN PdbNameSize;\r
923 UINTN MapNameSize;\r
924 CHAR8 *PurePdbFileName;\r
925 UINTN Index;\r
926\r
927 //\r
928 // remove dir name\r
929 //\r
930 PurePdbFileName = PdbFileName;\r
931 for (Index = 0; PdbFileName[Index] != 0; Index++) {\r
932 if (PdbFileName[Index] == '\\') {\r
933 PurePdbFileName = &PdbFileName[Index + 1];\r
934 }\r
935 }\r
936 PdbFileName = PurePdbFileName;\r
937\r
938 //\r
939 // get size\r
940 //\r
941 PdbNameSize = AsciiStrLen (PdbFileName);\r
942 MapNameSize = StrLen (MapFileName);\r
943\r
944 if (PdbNameSize != MapNameSize) {\r
945 return FALSE;\r
946 }\r
947\r
948 //\r
949 // check the name\r
950 //\r
951 for (Index = 0; Index < MapNameSize - 4; Index++) {\r
952 if ((PdbFileName[Index] | 0x20) != (MapFileName[Index] | 0x20)) {\r
953 return FALSE;\r
954 }\r
955 }\r
956\r
957 return TRUE;\r
958}\r
959\r
960//\r
961// BUGBUG: work-around start\r
962//\r
963typedef struct {\r
964 EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;\r
965 volatile UINT32 UpdateStatus;\r
966 UINT32 TableSize;\r
967} EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD;\r
968\r
969EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugImageInfoTableHeader;\r
970\r
971VOID\r
972EdbFixDebugImageInfoTable (\r
973 IN OUT EFI_DEBUG_IMAGE_INFO_TABLE_HEADER **DebugImageInfoTableHeader\r
974 )\r
975/*\r
976For compatibility consideration, we handle 2 cases:\r
977\r
9781) IA32:\r
979 Old: New:\r
980 +------------------------+ +------------------------+\r
981 | EfiDebugImageInfoTable | | UpdateStatus |\r
982 +------------------------+ +------------------------+\r
983 | UpdateStatus | | TableSize |\r
984 +------------------------+ +------------------------+\r
985 | TableSize | | EfiDebugImageInfoTable |\r
986 +------------------------+ +------------------------+\r
987\r
9882) X64 and IPF:\r
989 Old: New:\r
990 +------------------------+ +------------------------+\r
991 | EfiDebugImageInfoTable | | UpdateStatus |\r
992 | | +------------------------+\r
993 | | | TableSize |\r
994 +------------------------+ +------------------------+\r
995 | UpdateStatus | | EfiDebugImageInfoTable |\r
996 +------------------------+ | |\r
997 | TableSize | | |\r
998 +------------------------+ +------------------------+\r
999\r
1000*/\r
1001{\r
1002 mDebugImageInfoTableHeader.EfiDebugImageInfoTable = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->EfiDebugImageInfoTable;\r
1003 mDebugImageInfoTableHeader.UpdateStatus = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->UpdateStatus;\r
1004 mDebugImageInfoTableHeader.TableSize = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->TableSize;\r
1005\r
1006 if ((*DebugImageInfoTableHeader)->UpdateStatus > 3) {\r
1007 *DebugImageInfoTableHeader = &mDebugImageInfoTableHeader;\r
1008 return ;\r
1009 }\r
1010\r
1011 if ((*DebugImageInfoTableHeader)->TableSize % (EFI_PAGE_SIZE / (sizeof (VOID *))) != 0) {\r
1012 *DebugImageInfoTableHeader = &mDebugImageInfoTableHeader;\r
1013 return ;\r
1014 }\r
1015\r
1016 return ;\r
1017}\r
1018//\r
1019// BUGBUG: work-around end\r
1020//\r
1021\r
1022EFI_STATUS\r
1023EdbPatchSymbolRVA (\r
1024 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
1025 IN CHAR16 *FileName,\r
1026 IN EDB_EBC_IMAGE_RVA_SEARCH_TYPE SearchType\r
1027 )\r
1028/*++\r
1029\r
1030Routine Description:\r
1031\r
1032 Patch symbol RVA\r
1033\r
1034Arguments:\r
1035\r
1036 DebuggerPrivate - EBC Debugger private data structure\r
1037 FileName - Symbol file name\r
1038 SearchType - Search type for Object\r
1039\r
1040Returns:\r
1041\r
1042 EFI_SUCCESS - Patch symbol RVA successfully\r
1043 EFI_NOT_FOUND - Symbol RVA base not found\r
1044\r
1045--*/\r
1046{\r
1047 EFI_STATUS Status;\r
1048 UINTN ImageNumber;\r
1049 EFI_DEBUG_IMAGE_INFO *ImageTable;\r
1050 CHAR8 *PdbPath;\r
1051 VOID *ImageBase;\r
1052 VOID *CandidateImageBase;\r
1053 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
1054\r
1055 if (SearchType < 0 || SearchType >= EdbEbcImageRvaSearchTypeMax) {\r
1056 return EFI_INVALID_PARAMETER;\r
1057 }\r
1058\r
1059 //\r
1060 // Get the related object\r
1061 //\r
1062 Object = EdbFindSymbolFile (DebuggerPrivate, FileName, NULL);\r
1063 if (Object == NULL) {\r
1064 return EFI_NOT_FOUND;\r
1065 }\r
1066\r
1067 //\r
1068 // Try again to get DebugImageInfoTable\r
1069 //\r
1070 if (mDebuggerPrivate.DebugImageInfoTableHeader == NULL) {\r
1071 Status = EfiGetSystemConfigurationTable (\r
1072 &gEfiDebugImageInfoTableGuid,\r
1073 (VOID **) &mDebuggerPrivate.DebugImageInfoTableHeader\r
1074 );\r
1075 if (EFI_ERROR (Status)) {\r
1076 EDBPrint (L"DebugImageInfoTable not found!\n");\r
1077 return Status;\r
1078 }\r
1079 }\r
1080 DEBUG ((DEBUG_ERROR, "DebugImageInfoTableHeader: %x\n", mDebuggerPrivate.DebugImageInfoTableHeader));\r
1081\r
1082 //\r
1083 // BUGBUG: work-around start\r
1084 //\r
1085 EdbFixDebugImageInfoTable (&mDebuggerPrivate.DebugImageInfoTableHeader);\r
1086 //\r
1087 // BUGBUG: work-around end\r
1088 //\r
1089\r
1090 //\r
1091 // Go through DebugImageInfoTable for each Image\r
1092 //\r
1093 CandidateImageBase = NULL;\r
1094 ImageTable = mDebuggerPrivate.DebugImageInfoTableHeader->EfiDebugImageInfoTable;\r
1095 for (ImageNumber = 0; ImageNumber < mDebuggerPrivate.DebugImageInfoTableHeader->TableSize; ImageNumber++) {\r
1096 if (ImageTable[ImageNumber].NormalImage == NULL) {\r
1097 continue;\r
1098 }\r
1099 ImageBase = ImageTable[ImageNumber].NormalImage->LoadedImageProtocolInstance->ImageBase;\r
1100 //\r
1101 // Get PDB path\r
1102 //\r
1103 PdbPath = GetPdbPath (ImageBase);\r
1104 if (PdbPath == NULL) {\r
1105 continue;\r
1106 }\r
1107 //\r
1108 // Check PDB name\r
1109 //\r
1110 if (!MatchPdbAndMap (PdbPath, FileName)) {\r
1111 continue;\r
1112 }\r
1113 DEBUG ((DEBUG_ERROR, "ImageBase: %x\n", ImageBase));\r
1114\r
1115 //\r
1116 // Check SearchType\r
1117 //\r
1118 if (SearchType == EdbEbcImageRvaSearchTypeAny || SearchType == EdbEbcImageRvaSearchTypeFirst) {\r
1119 //\r
1120 // Assign base address and return\r
1121 //\r
1122 Object->BaseAddress = (UINTN)ImageBase;\r
1123 return EFI_SUCCESS;\r
1124 }\r
1125\r
1126 //\r
1127 // Get CandidateImageBase for EdbEbcImageRvaSearchTypeLast\r
1128 //\r
1129 CandidateImageBase = ImageBase;\r
1130 }\r
1131\r
1132 //\r
1133 // Check EdbEbcImageRvaSearchTypeLast\r
1134 //\r
1135 if (SearchType == EdbEbcImageRvaSearchTypeLast) {\r
1136 if (CandidateImageBase == NULL) {\r
1137 return EFI_NOT_FOUND;\r
1138 }\r
1139 //\r
1140 // Assign base address and return\r
1141 //\r
1142 Object->BaseAddress = (UINTN)CandidateImageBase;\r
1143 return EFI_SUCCESS;\r
1144 }\r
1145\r
1146 //\r
1147 // No match\r
1148 //\r
1149 return EFI_NOT_FOUND;\r
1150}\r
1151\r
1152BOOLEAN\r
1153MatchObjAndCod (\r
1154 IN CHAR8 *ObjFileName,\r
1155 IN CHAR16 *CodFileName\r
1156 )\r
1157/*++\r
1158\r
1159Routine Description:\r
1160\r
1161 Check whether OBJ file and COD file have same name\r
1162\r
1163Arguments:\r
1164\r
1165 ObjFileName - OBJ file name\r
1166 CodFileName - COD file name\r
1167\r
1168Returns:\r
1169\r
1170 TRUE - OBJ and COD file name match\r
1171 FALSE - OBJ and COD file name not match\r
1172\r
1173--*/\r
1174{\r
1175 UINTN ObjNameSize;\r
1176 UINTN CodNameSize;\r
1177 CHAR8 *PureObjFileName;\r
1178 UINTN Index;\r
1179\r
1180 //\r
1181 // remove library name\r
1182 //\r
1183 PureObjFileName = ObjFileName;\r
1184 for (Index = 0; ObjFileName[Index] != 0; Index++) {\r
1185 if (ObjFileName[Index] == ':') {\r
1186 PureObjFileName = &ObjFileName[Index + 1];\r
1187 break;\r
1188 }\r
1189 }\r
1190 ObjFileName = PureObjFileName;\r
1191\r
1192 //\r
1193 // get size\r
1194 //\r
1195 ObjNameSize = AsciiStrLen (ObjFileName);\r
1196 CodNameSize = StrLen (CodFileName);\r
1197\r
1198 if (ObjNameSize != CodNameSize) {\r
1199 return FALSE;\r
1200 }\r
1201\r
1202 //\r
1203 // check the name\r
1204 //\r
1205 for (Index = 0; Index < CodNameSize - 4; Index++) {\r
1206 if ((ObjFileName[Index] | 0x20) != (CodFileName[Index] | 0x20)) {\r
1207 return FALSE;\r
1208 }\r
1209 }\r
1210\r
1211 return TRUE;\r
1212}\r
1213\r
1214typedef enum {\r
1215 EdbEbcCodParseStateUninitialized,\r
1216 EdbEbcCodParseStateSymbolInitialized,\r
1217 EdbEbcCodParseStateSymbolStart,\r
1218 EdbEbcCodParseStateSymbolEnd,\r
1219 EdbEbcCodParseStateMax,\r
1220} EDB_EBC_COD_PARSE_STATE;\r
1221\r
1222/*++\r
1223\r
1224 The following code depends on the COD file generated by IEC compiler.\r
1225\r
1226 Sample as follows: EbcTest.cod\r
1227===============================================================================\r
1228; -- Machine type EFI\r
1229; mark_description "Intel(R) C Compiler for EFI Byte Code, Version 1.2 Build 20040123";\r
1230; mark_description "XXX";\r
1231;ident "Intel(R) C Compiler for EFI Byte Code, Version 1.2 Build 20040123"\r
1232;ident "XXX"\r
1233 .686P\r
1234 .387\r
1235_TEXT SEGMENT PARA PUBLIC USE32 'CODE'\r
1236_TEXT ENDS\r
1237_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1238 ALIGN 010H\r
1239_DATA ENDS\r
1240_BSS SEGMENT PARA PUBLIC USE32 'BSS'\r
1241 ALIGN 010H\r
1242_BSS ENDS\r
1243_VARBSS SEGMENT PARA PUBLIC USE32 'BSS'\r
1244 ALIGN 010H\r
1245_VARBSS ENDS\r
1246 ASSUME CS:FLAT,DS:FLAT,SS:FLAT\r
1247_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1248TestVariable2 DD 000000003H,000000000H ; u64\r
1249_DATA ENDS\r
1250_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1251_DATA ENDS\r
1252_TEXT SEGMENT PARA PUBLIC USE32 'CODE'\r
1253; -- Begin EfiMain\r
1254; mark_begin;\r
1255 PUBLIC EfiMain\r
1256EfiMain PROC NEAR\r
1257$B3$1:; 11a\r
1258$LN45:\r
1259\r
1260;117 ; {\r
1261\r
1262 0011a 60 00 70 80 MOVqw R0, R0(+0,-112) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:117\r
1263$LN46:\r
1264\r
1265;118 ; UINT16 test = 0x1234;\r
1266\r
1267 0011e 77 58 58 00 34\r
1268 12 MOVIww @R0(+0,+88), +4660 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:118\r
1269$LN47:\r
1270\r
1271;121 ; EFI_STATUS Status;\r
1272;121 ;\r
1273;121 ; SystemTable->ConOut->OutputString (\r
1274\r
1275 00124 72 87 01 12 MOVnw R7, @R0(+1,+128) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:121\r
1276 00128 72 f7 85 21 MOVnw R7, @R7(+5,+24) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:121\r
1277$LN48:\r
1278\r
1279;122 ; SystemTable->ConOut,\r
1280\r
1281 0012c 72 84 01 12 MOVnw R4, @R0(+1,+128) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:122\r
1282 00130 72 c8 85 21 MOVnw @R0, @R4(+5,+24) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:122\r
1283 00134 b9 34 00 00 00\r
1284 00 MOVreld R4, __STRING$1 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:122\r
1285 0013a b2 48 01 10 MOVnw @R0(+1,+0), R4 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:122\r
1286 0013e 83 2f 01 00 00\r
1287 10 CALLEX @R7(+1,+0) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:122\r
1288$B3$2:; 144\r
1289$LN49:\r
1290\r
1291;125 ; L"Hello EBC Test!\n\r"\r
1292;125 ; );\r
1293;125 ; EFI_BREAKPOINT ();\r
1294\r
1295 00144 00 03 BREAK 3 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:125\r
1296$B3$3:; 146\r
1297$LN50:\r
1298\r
1299;126 ; TestVariable1 = 6;\r
1300\r
1301 00146 b9 37 00 00 00\r
1302 00 MOVreld R7, TestVariable1 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:126\r
1303 0014c 78 0f 06 00 MOVInw @R7, (0,6) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:126\r
1304$LN51:\r
1305\r
1306;127 ; TestSubRoutineSub (1, 5);\r
1307\r
1308 00150 78 08 01 00 MOVInw @R0, (0,1) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:127\r
1309 00154 78 48 01 10 05\r
1310 00 MOVInw @R0(1,0), (0,5) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:127\r
1311 0015a 83 10 00 00 00\r
1312 00 CALL TestSubRoutineSub ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:127\r
1313$B3$4:; 160\r
1314$LN52:\r
1315\r
1316;129 ;\r
1317;129 ; SystemTable->ConOut->OutputString (\r
1318\r
1319 00160 72 87 01 12 MOVnw R7, @R0(+1,+128) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:129\r
1320 00164 72 f7 85 21 MOVnw R7, @R7(+5,+24) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:129\r
1321$LN53:\r
1322\r
1323;130 ; SystemTable->ConOut,\r
1324\r
1325 00168 72 84 01 12 MOVnw R4, @R0(+1,+128) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:130\r
1326 0016c 72 c8 85 21 MOVnw @R0, @R4(+5,+24) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:130\r
1327$LN54:\r
1328\r
1329;131 ; TestStr\r
1330\r
1331 00170 b9 34 00 00 00\r
1332 00 MOVreld R4, TestStr ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:131\r
1333 00176 b2 c8 01 10 MOVnw @R0(+1, +0), @R4 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:131\r
1334 0017a 83 2f 01 00 00\r
1335 10 CALLEX @R7(+1,+0) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:131\r
1336$B3$5:; 180\r
1337$LN55:\r
1338\r
1339;134 ; );\r
1340;134 ;\r
1341;134 ; test = test & 0xFF;\r
1342\r
1343 00180 de 88 58 00 58\r
1344 00 MOVww @R0(+0,+88), @R0(+0,+88) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:134\r
1345$LN56:\r
1346\r
1347;139 ; if (test != 0x34) {\r
1348;139 ; // EFI_BREAKPOINT ();\r
1349;139 ; }\r
1350;139 ;\r
1351;139 ; Status = TestSubRoutine (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\r
1352\r
1353 00186 78 08 01 00 MOVInw @R0, (0,1) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1354 0018a 78 48 01 10 02\r
1355 00 MOVInw @R0(1,0), (0,2) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1356 00190 78 48 02 10 03\r
1357 00 MOVInw @R0(2,0), (0,3) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1358 00196 78 48 03 10 04\r
1359 00 MOVInw @R0(3,0), (0,4) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1360 0019c 78 48 04 20 05\r
1361 00 MOVInw @R0(4,0), (0,5) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1362 001a2 78 48 05 20 06\r
1363 00 MOVInw @R0(5,0), (0,6) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1364 001a8 78 48 06 20 07\r
1365 00 MOVInw @R0(6,0), (0,7) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1366 001ae 78 48 07 20 08\r
1367 00 MOVInw @R0(7,0), (0,8) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1368 001b4 78 48 08 20 09\r
1369 00 MOVInw @R0(8,0), (0,9) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1370 001ba 78 48 09 20 0a\r
1371 00 MOVInw @R0(9,0), (0,10) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1372 001c0 83 10 00 00 00\r
1373 00 CALL TestSubRoutine ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1374$B3$10:; 1c6\r
1375 001c6 b2 78 60 00 MOVnw @R0(+0,+96), R7 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1376$B3$6:; 1ca\r
1377$LN57:\r
1378 001ca f2 88 50 00 60\r
1379 00 MOVnw @R0(+0,+80), @R0(+0,+96) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:139\r
1380$LN58:\r
1381\r
1382;141 ;\r
1383;141 ; SystemTable->ConOut->OutputString (\r
1384\r
1385 001d0 72 87 01 12 MOVnw R7, @R0(+1,+128) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:141\r
1386 001d4 72 f7 85 21 MOVnw R7, @R7(+5,+24) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:141\r
1387$LN59:\r
1388\r
1389;142 ; SystemTable->ConOut,\r
1390\r
1391 001d8 72 84 01 12 MOVnw R4, @R0(+1,+128) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:142\r
1392 001dc 72 c8 85 21 MOVnw @R0, @R4(+5,+24) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:142\r
1393 001e0 b9 34 00 00 00\r
1394 00 MOVreld R4, __STRING$2 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:142\r
1395 001e6 b2 48 01 10 MOVnw @R0(+1,+0), R4 ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:142\r
1396 001ea 83 2f 01 00 00\r
1397 10 CALLEX @R7(+1,+0) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:142\r
1398$B3$7:; 1f0\r
1399$LN60:\r
1400\r
1401;146 ; L"Goodbye EBC Test!\n\r"\r
1402;146 ; );\r
1403;146 ;\r
1404;146 ; return Status;\r
1405\r
1406 001f0 72 87 50 00 MOVnw R7, @R0(+0,+80) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:146\r
1407 001f4 60 00 70 00 MOVqw R0, R0(+0,+112) ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:146\r
1408 001f8 04 00 RET ;C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest.c:146\r
1409; mark_end;\r
1410EfiMain ENDP\r
1411_TEXT ENDS\r
1412_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1413 DB 3 DUP (0) ; pad\r
1414__STRING$2 DW 71 ; u16\r
1415 DW 111 ; u16\r
1416 DW 111 ; u16\r
1417 DW 100 ; u16\r
1418 DW 98 ; u16\r
1419 DW 121 ; u16\r
1420 DW 101 ; u16\r
1421 DW 32 ; u16\r
1422 DW 69 ; u16\r
1423 DW 66 ; u16\r
1424 DW 67 ; u16\r
1425 DW 32 ; u16\r
1426 DW 84 ; u16\r
1427 DW 101 ; u16\r
1428 DW 115 ; u16\r
1429 DW 116 ; u16\r
1430 DW 33 ; u16\r
1431 DW 10 ; u16\r
1432 DW 13 ; u16\r
1433 DW 0 ; u16\r
1434__STRING$1 DW 72 ; u16\r
1435 DW 101 ; u16\r
1436 DW 108 ; u16\r
1437 DW 108 ; u16\r
1438 DW 111 ; u16\r
1439 DW 32 ; u16\r
1440 DW 69 ; u16\r
1441 DW 66 ; u16\r
1442 DW 67 ; u16\r
1443 DW 32 ; u16\r
1444 DW 84 ; u16\r
1445 DW 101 ; u16\r
1446 DW 115 ; u16\r
1447 DW 116 ; u16\r
1448 DW 33 ; u16\r
1449 DW 10 ; u16\r
1450 DW 13 ; u16\r
1451 DW 0 ; u16\r
1452_DATA ENDS\r
1453_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1454_DATA ENDS\r
1455; -- End EfiMain\r
1456_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1457__STRING$0 DW 55 ; u16\r
1458 DW 56 ; u16\r
1459 DW 57 ; u16\r
1460 DW 52 ; u16\r
1461 DW 53 ; u16\r
1462 DW 54 ; u16\r
1463 DW 49 ; u16\r
1464 DW 50 ; u16\r
1465 DW 51 ; u16\r
1466 DW 13 ; u16\r
1467 DW 10 ; u16\r
1468 DW 0 ; u16\r
1469_DATA ENDS\r
1470_VARBSS SEGMENT PARA PUBLIC USE32 'BSS'\r
1471 PUBLIC TestStr\r
1472TestStr DD 2 DUP (?) ; pad\r
1473 PUBLIC TestVariable1\r
1474TestVariable1 DD 2 DUP (?) ; pad\r
1475_VARBSS ENDS\r
1476_VARBSS_INIT SEGMENT DWORD PUBLIC USE32 'CODE'\r
1477; -- Begin varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest$c45b815d2\r
1478 PUBLIC varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest$c45b815d2\r
1479varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest$c45b815d2 PROC NEAR\r
1480 00000 b9 34 00 00 00\r
1481 00 MOVreld R4, TestStr\r
1482 00006 b9 35 00 00 00\r
1483 00 MOVreld R5, __STRING$0\r
1484 0000c 33 5c MOVnd @R4, R5\r
1485 0000e b9 34 00 00 00\r
1486 00 MOVreld R4, TestVariable1\r
1487 00014 78 0c 04 00 MOVInw @R4, (0,4)\r
1488 00018 04 00 RET\r
1489; -- End varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest$c45b815d2\r
1490_VARBSS_INIT ENDS\r
1491_DATA SEGMENT PARA PUBLIC USE32 'DATA'\r
1492_DATA ENDS\r
1493EXTRN TestSubRoutineSub:PROC\r
1494 END\r
1495\r
1496===============================================================================\r
1497\r
1498--*/\r
1499CHAR8 *\r
1500EdbLoadCodBySymbolByIec (\r
1501 IN CHAR8 *Name,\r
1502 IN VOID *Buffer,\r
1503 IN UINTN BufferSize,\r
1504 OUT UINTN *CodeBufferSize,\r
1505 OUT UINTN *FuncOffset\r
1506 )\r
1507/*++\r
1508\r
1509Routine Description:\r
1510\r
1511 Load code by symbol by Iec\r
1512\r
1513Arguments:\r
1514\r
1515 Name - Symbol file name\r
1516 BufferSize - Symbol file buffer size\r
1517 Buffer - Symbol file buffer\r
1518 CodeBufferSize - Code buffer size\r
1519 FuncOffset - Code funcion offset\r
1520\r
1521Returns:\r
1522\r
1523 CodeBuffer\r
1524\r
1525--*/\r
1526{\r
1527 CHAR8 *LineBuffer;\r
1528 CHAR8 *FieldBuffer;\r
1529 VOID *BufferStart;\r
1530 VOID *BufferEnd;\r
1531 UINTN Offset;\r
1532 EDB_EBC_COD_PARSE_STATE CodParseState;\r
1533 CHAR8 Char[2] = {9, 0};\r
1534\r
1535 //\r
1536 // Init\r
1537 //\r
1538 LineBuffer = AsciiStrGetNewTokenLine (Buffer, "\n\r");\r
1539 Offset = (UINTN)-1;\r
1540 BufferStart = NULL;\r
1541 BufferEnd = NULL;\r
1542 CodParseState = EdbEbcCodParseStateUninitialized;\r
1543\r
1544 //\r
1545 // Check each line\r
1546 //\r
1547 while (LineBuffer != NULL) {\r
1548 switch (CodParseState) {\r
1549 case EdbEbcCodParseStateUninitialized:\r
1550 //\r
1551 // check mark_begin, begin to check line after this match\r
1552 //\r
1553 if (AsciiStrCmp (LineBuffer, "; mark_begin;") == 0) {\r
1554 CodParseState = EdbEbcCodParseStateSymbolInitialized;\r
1555 }\r
1556 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");\r
1557 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
1558 break;\r
1559\r
1560 case EdbEbcCodParseStateSymbolInitialized:\r
1561 //\r
1562 // check mark_end, not check line after this match\r
1563 //\r
1564 if (AsciiStrCmp (LineBuffer, "; mark_end;") == 0) {\r
1565 CodParseState = EdbEbcCodParseStateUninitialized;\r
1566 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");\r
1567 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
1568 break;\r
1569 }\r
1570\r
1571 //\r
1572 // not check this line if the first char is as follows\r
1573 //\r
1574 if ((*LineBuffer == 0) ||\r
1575 (*LineBuffer == '$') ||\r
1576 (*LineBuffer == ';') ||\r
1577 (*LineBuffer == '_') ||\r
1578 (*LineBuffer == ' ')) {\r
1579 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");\r
1580 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
1581 break;\r
1582 }\r
1583\r
1584 //\r
1585 // get function name, function name is followed by char 0x09.\r
1586 //\r
1587 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, Char);\r
eebfb7b2 1588 ASSERT (FieldBuffer != NULL);\r
748edcd5
PB
1589 if (AsciiStriCmp (FieldBuffer, Name) == 0) {\r
1590 BufferStart = FieldBuffer;\r
1591 CodParseState = EdbEbcCodParseStateSymbolStart;\r
1592 }\r
1593 PatchForAsciiStrTokenAfter (FieldBuffer, 0x9);\r
1594\r
1595 //\r
1596 // Get next line\r
1597 //\r
1598 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");\r
1599 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
1600 break;\r
1601\r
1602 case EdbEbcCodParseStateSymbolStart:\r
1603 //\r
1604 // check mark_end, if this match, means the function is found successfully.\r
1605 //\r
1606 if (AsciiStrCmp (LineBuffer, "; mark_end;") == 0) {\r
1607 CodParseState = EdbEbcCodParseStateSymbolEnd;\r
1608 //\r
1609 // prepare CodeBufferSize, FuncOffset, and FuncStart to return\r
1610 //\r
1611 BufferEnd = LineBuffer + sizeof("; mark_end;") - 1;\r
1612 *CodeBufferSize = (UINTN)BufferEnd - (UINTN)BufferStart;\r
1613 *FuncOffset = Offset;\r
1614 PatchForAsciiStrTokenAfter (LineBuffer, '\n');\r
1615 return BufferStart;\r
1616 }\r
1617\r
1618 //\r
1619 // Get function offset\r
1620 //\r
1621 if ((Offset == (UINTN)-1) &&\r
1622 (*LineBuffer == ' ')) {\r
1623 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 2, " ");\r
1624 Offset = AsciiXtoi (FieldBuffer);\r
1625 PatchForAsciiStrTokenAfter (FieldBuffer, ' ');\r
1626 }\r
1627\r
1628 //\r
1629 // Get next line\r
1630 //\r
1631 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");\r
1632 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
1633 break;\r
1634\r
1635 case EdbEbcCodParseStateSymbolEnd:\r
1636 break;\r
1637\r
1638 default:\r
1639 break;\r
1640 }\r
1641 }\r
1642\r
1643 //\r
1644 // no function found\r
1645 //\r
1646 return NULL;\r
1647}\r
1648\r
1649CHAR8 *\r
1650EdbLoadCodBySymbol (\r
1651 IN CHAR8 *Name,\r
1652 IN VOID *Buffer,\r
1653 IN UINTN BufferSize,\r
1654 OUT UINTN *CodeBufferSize,\r
1655 OUT UINTN *FuncOffset\r
1656 )\r
1657/*++\r
1658\r
1659Routine Description:\r
1660\r
1661 Load code by symbol\r
1662\r
1663Arguments:\r
1664\r
1665 Name - Symbol file name\r
1666 BufferSize - Symbol file buffer size\r
1667 Buffer - Symbol file buffer\r
1668 CodeBufferSize - Code buffer size\r
1669 FuncOffset - Code funcion offset\r
1670\r
1671Returns:\r
1672\r
1673 CodeBuffer\r
1674\r
1675--*/\r
1676{\r
1677 //\r
1678 // COD file format depends on the compiler.\r
1679 //\r
1680 // It is possible to check the different COD file format in this routine.\r
1681 // Now only IEC is supported.\r
1682 //\r
1683 return EdbLoadCodBySymbolByIec (Name, Buffer, BufferSize, CodeBufferSize, FuncOffset);\r
1684}\r
1685\r
1686VOID *\r
1687EdbFindCodeFromObject (\r
1688 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
1689 IN EFI_DEBUGGER_SYMBOL_OBJECT *Object,\r
1690 IN CHAR16 *FileName\r
1691 )\r
1692/*++\r
1693\r
1694Routine Description:\r
1695\r
1696 Find code from object\r
1697\r
1698Arguments:\r
1699\r
1700 Object - Symbol object\r
1701 FileName - File name\r
1702\r
1703Returns:\r
1704\r
1705 CodeBuffer\r
1706\r
1707--*/\r
1708{\r
1709 UINTN EntryIndex;\r
1710\r
1711 //\r
1712 // Go througn each Entry in this Object\r
1713 //\r
1714 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {\r
1715 //\r
1716 // This check is for Function only\r
1717 //\r
1718 if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&\r
1719 (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction)) {\r
1720 continue;\r
1721 }\r
1722 //\r
1723 // Skip match varbss_init function, because they has no source code\r
1724 //\r
1725 if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof("varbss_init") - 1) == 0) {\r
1726 continue;\r
1727 }\r
1728 //\r
1729 // check the name\r
1730 //\r
1731 if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {\r
1732 continue;\r
1733 }\r
1734 //\r
1735 // found it, return source buffer\r
1736 //\r
1737 if (Object->Entry[EntryIndex].CodBuffer != NULL) {\r
1738 return Object->Entry[EntryIndex].SourceBuffer;\r
1739 }\r
1740 }\r
1741\r
1742 //\r
1743 // not found\r
1744 //\r
1745 return NULL;\r
1746}\r
1747\r
1748EFI_STATUS\r
1749EdbLoadCode (\r
1750 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
1751 IN CHAR16 *MapFileName,\r
1752 IN CHAR16 *FileName,\r
1753 IN UINTN BufferSize,\r
1754 IN VOID *Buffer\r
1755 )\r
1756/*++\r
1757\r
1758Routine Description:\r
1759\r
1760 Load code\r
1761\r
1762Arguments:\r
1763\r
1764 DebuggerPrivate - EBC Debugger private data structure\r
1765 MapFileName - Symbol file name\r
1766 FileName - Code file name\r
1767 BufferSize - Code file buffer size\r
1768 Buffer - Code file buffer\r
1769\r
1770Returns:\r
1771\r
1772 EFI_SUCCESS - Code loaded successfully\r
1773\r
1774--*/\r
1775{\r
1776 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
1777 UINTN ObjectIndex;\r
1778 UINTN EntryIndex;\r
1779 VOID *SourceBuffer;\r
1780 EFI_STATUS Status;\r
1781\r
1782 //\r
1783 // Find Symbol\r
1784 //\r
1785 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, &ObjectIndex);\r
1786 if (Object == NULL) {\r
1787 EDBPrint (L"SymbolFile is not loaded!\n");\r
1788 return EFI_NOT_FOUND;\r
1789 } else {\r
1790 //\r
1791 // Check duplicated File\r
1792 //\r
1793 SourceBuffer = EdbFindCodeFromObject (DebuggerPrivate, Object, FileName);\r
1794 if (SourceBuffer != NULL) {\r
1795 //\r
1796 // unnload duplicated code\r
1797 //\r
1798 Status = EdbUnloadCode (DebuggerPrivate, MapFileName, FileName, &SourceBuffer);\r
1799 if (EFI_ERROR(Status)) {\r
1800 DEBUG ((DEBUG_ERROR, "Unload Duplicated Code File Error!\n"));\r
1801 return Status;\r
1802 }\r
1803 Status = EdbDeleteCodeBuffer (DebuggerPrivate, MapFileName, FileName, SourceBuffer);\r
1804 if (EFI_ERROR(Status)) {\r
1805 DEBUG ((DEBUG_ERROR, "Delete Duplicated Code File Error!\n"));\r
1806 return Status;\r
1807 }\r
1808 }\r
1809 }\r
1810\r
1811 //\r
1812 // Go through each SymbolEntry\r
1813 //\r
1814 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {\r
1815 //\r
1816 // load symbol for function only\r
1817 //\r
1818 if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&\r
1819 (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction)) {\r
1820 continue;\r
1821 }\r
1822 //\r
1823 // skip varbss_init\r
1824 //\r
1825 if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof("varbss_init") - 1) == 0) {\r
1826 continue;\r
1827 }\r
1828 //\r
1829 // Check the name\r
1830 //\r
1831 if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {\r
1832 continue;\r
1833 }\r
1834 //\r
1835 // load code for this symbol\r
1836 //\r
1837 Object->Entry[EntryIndex].CodBuffer = EdbLoadCodBySymbol (\r
1838 Object->Entry[EntryIndex].Name,\r
1839 Buffer,\r
1840 BufferSize,\r
1841 &Object->Entry[EntryIndex].CodBufferSize,\r
1842 &Object->Entry[EntryIndex].FuncOffsetBase\r
1843 );\r
1844 if (Object->Entry[EntryIndex].CodBuffer != NULL) {\r
1845 Object->Entry[EntryIndex].SourceBuffer = Buffer;\r
1846 }\r
1847 }\r
1848\r
1849 //\r
1850 // patch end '\0' for each code buffer\r
1851 //\r
1852 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {\r
1853 if (Object->Entry[EntryIndex].CodBuffer != NULL) {\r
1854 *((UINT8 *)Object->Entry[EntryIndex].CodBuffer + Object->Entry[EntryIndex].CodBufferSize) = 0;\r
1855 DEBUG ((DEBUG_ERROR, " CodeSymbol: %a, FuncOffset: 0x05%x\n", Object->Entry[EntryIndex].Name, Object->Entry[EntryIndex].FuncOffsetBase));\r
1856// DEBUG ((DEBUG_ERROR, " [CODE]:\n%a\n", Object->Entry[EntryIndex].CodBuffer));\r
1857 }\r
1858 }\r
1859\r
1860 //\r
1861 // Done\r
1862 //\r
1863 return EFI_SUCCESS;\r
1864}\r
1865\r
1866EFI_STATUS\r
1867EdbUnloadCode (\r
1868 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
1869 IN CHAR16 *MapFileName,\r
1870 IN CHAR16 *FileName,\r
1871 OUT VOID **Buffer\r
1872 )\r
1873/*++\r
1874\r
1875Routine Description:\r
1876\r
1877 Unload code\r
1878\r
1879Arguments:\r
1880\r
1881 DebuggerPrivate - EBC Debugger private data structure\r
1882 MapFileName - Symbol file name\r
1883 FileName - Code file name\r
1884 Buffer - Code file buffer\r
1885\r
1886Returns:\r
1887\r
1888 EFI_SUCCESS - Code unloaded successfully\r
1889\r
1890--*/\r
1891{\r
1892 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
1893 UINTN ObjectIndex;\r
1894 UINTN EntryIndex;\r
1895\r
1896 //\r
1897 // Find Symbol\r
1898 //\r
1899 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, &ObjectIndex);\r
1900 if (Object == NULL) {\r
1901 EDBPrint (L"SymbolFile is not loaded!\n");\r
1902 return EFI_NOT_FOUND;\r
1903 }\r
1904\r
1905 //\r
1906 // Find code\r
1907 //\r
1908 *Buffer = EdbFindCodeFromObject (DebuggerPrivate, Object, FileName);\r
1909 if (*Buffer == NULL) {\r
1910 EDBPrint (L"CodeFile is not loaded!\n");\r
1911 return EFI_NOT_FOUND;\r
1912 }\r
1913\r
1914 //\r
1915 // go through each entry\r
1916 //\r
1917 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {\r
1918 if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&\r
1919 (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction)) {\r
1920 continue;\r
1921 }\r
1922 if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof("varbss_init") - 1) == 0) {\r
1923 continue;\r
1924 }\r
1925 if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {\r
1926 continue;\r
1927 }\r
1928 //\r
1929 // clean up the buffer\r
1930 //\r
1931 Object->Entry[EntryIndex].CodBuffer = NULL;\r
1932 Object->Entry[EntryIndex].CodBufferSize = 0;\r
1933 Object->Entry[EntryIndex].FuncOffsetBase = 0;\r
1934 Object->Entry[EntryIndex].SourceBuffer = NULL;\r
1935 }\r
1936\r
1937 //\r
1938 // Done\r
1939 //\r
1940 return EFI_SUCCESS;\r
1941}\r
1942\r
1943EFI_STATUS\r
1944EdbAddCodeBuffer (\r
1945 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
1946 IN CHAR16 *MapFileName,\r
1947 IN CHAR16 *CodeFileName,\r
1948 IN UINTN SourceBufferSize,\r
1949 IN VOID *SourceBuffer\r
1950 )\r
1951/*++\r
1952\r
1953Routine Description:\r
1954\r
1955 Add code buffer\r
1956\r
1957Arguments:\r
1958\r
1959 DebuggerPrivate - EBC Debugger private data structure\r
1960 MapFileName - Symbol file name\r
1961 CodeFileName - Code file name\r
1962 SourceBufferSize- Code buffer size\r
1963 SourceBuffer - Code buffer\r
1964\r
1965Returns:\r
1966\r
1967 EFI_SUCCESS - CodeBuffer added successfully\r
1968\r
1969--*/\r
1970{\r
1971 UINTN Index;\r
1972 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
1973\r
1974 //\r
1975 // Find Symbol\r
1976 //\r
1977 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, NULL);\r
1978 if (Object == NULL) {\r
1979 EDBPrint (L"SymbolFile is not loaded!\n");\r
1980 return EFI_NOT_FOUND;\r
1981 }\r
1982\r
1983 //\r
1984 // Add it to last entry\r
1985 //\r
1986 for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {\r
1987 ;\r
1988 }\r
1989 Object->SourceBuffer[Index] = SourceBuffer;\r
1990\r
1991 return EFI_SUCCESS;\r
1992}\r
1993\r
1994EFI_STATUS\r
1995EdbDeleteCodeBuffer (\r
1996 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
1997 IN CHAR16 *MapFileName,\r
1998 IN CHAR16 *CodeFileName,\r
1999 IN VOID *SourceBuffer\r
2000 )\r
2001/*++\r
2002\r
2003Routine Description:\r
2004\r
2005 Delete code buffer\r
2006\r
2007Arguments:\r
2008\r
2009 DebuggerPrivate - EBC Debugger private data structure\r
2010 MapFileName - Symbol file name\r
2011 CodeFileName - Code file name\r
2012 SourceBuffer - Code buffer\r
2013\r
2014Returns:\r
2015\r
2016 EFI_SUCCESS - CodeBuffer deleted successfully\r
2017\r
2018--*/\r
2019{\r
2020 UINTN Index;\r
2021 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
2022\r
2023 //\r
2024 // Find Symbol\r
2025 //\r
2026 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, NULL);\r
2027 if (Object == NULL) {\r
2028 EDBPrint (L"SymbolFile is not loaded!\n");\r
2029 return EFI_NOT_FOUND;\r
2030 }\r
2031\r
2032 for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {\r
2033 //\r
2034 // free the buffer if match\r
2035 //\r
2036 if (Object->SourceBuffer[Index] == SourceBuffer) {\r
2037 gBS->FreePool (SourceBuffer);\r
2038 break;\r
2039 }\r
2040 }\r
2041\r
2042 if (Object->SourceBuffer[Index] == NULL) {\r
2043 //\r
2044 // not return NOT_FOUND\r
2045 //\r
2046 return EFI_SUCCESS;\r
2047 }\r
2048\r
2049 //\r
2050 // remove the entry\r
2051 //\r
2052 Object->SourceBuffer[Index] = NULL;\r
2053 for (Index = Index + 1; Object->SourceBuffer[Index] != NULL; Index++) {\r
2054 Object->SourceBuffer[Index - 1] = Object->SourceBuffer[Index];\r
2055 }\r
2056 Object->SourceBuffer[Index - 1] = NULL;\r
2057\r
2058 return EFI_SUCCESS;\r
2059}\r
2060\r
2061CHAR8 *\r
2062FindSymbolStr (\r
2063 IN UINTN Address\r
2064 )\r
2065/*++\r
2066\r
2067Routine Description:\r
2068\r
2069 Find the symbol string according to address\r
2070\r
2071Arguments:\r
2072\r
2073 Address - Symbol address\r
2074\r
2075Returns:\r
2076\r
2077 Symbol string\r
2078\r
2079--*/\r
2080{\r
2081 UINTN ObjectIndex;\r
2082 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
2083 UINTN EntryIndex;\r
2084 EFI_DEBUGGER_SYMBOL_ENTRY *Entry;\r
2085\r
2086 //\r
2087 // need we display symbol\r
2088 //\r
2089 if (!mDebuggerPrivate.DebuggerSymbolContext.DisplaySymbol) {\r
2090 return NULL;\r
2091 }\r
2092\r
2093 //\r
2094 // Go through each object and entry\r
2095 //\r
2096 Object = mDebuggerPrivate.DebuggerSymbolContext.Object;\r
2097 for (ObjectIndex = 0; ObjectIndex < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; ObjectIndex++) {\r
2098 Entry = Object[ObjectIndex].Entry;\r
2099 for (EntryIndex = 0; EntryIndex < Object[ObjectIndex].EntryCount; EntryIndex++) {\r
2100 //\r
2101 // if Address match, return Name\r
2102 //\r
2103 if (Address == (Entry[EntryIndex].RVA + Object[ObjectIndex].BaseAddress)) {\r
2104 return Entry[EntryIndex].Name;\r
2105 }\r
2106 }\r
2107 }\r
2108\r
2109 //\r
2110 // not found\r
2111 //\r
2112 return NULL;\r
2113}\r
2114\r
2115UINTN\r
2116EdbGetLineNumberAndOffsetFromThisLine (\r
2117 IN VOID *Line,\r
2118 OUT UINTN *Offset\r
2119 )\r
2120/*++\r
2121\r
2122Routine Description:\r
2123\r
2124 Get line number and offset from this line in code file\r
2125\r
2126Arguments:\r
2127\r
2128 Line - Line buffer in code file\r
2129 Offset - Offset to functin entry\r
2130\r
2131Returns:\r
2132\r
2133 Line number\r
2134\r
2135--*/\r
2136{\r
2137 UINTN LineNumber;\r
2138 CHAR8 *LineBuffer;\r
2139 CHAR8 *FieldBuffer;\r
2140\r
2141 LineNumber = (UINTN)-1;\r
2142 LineBuffer = Line;\r
2143 *Offset = (UINTN)-1;\r
2144\r
2145 while (LineBuffer != NULL) {\r
2146 //\r
2147 // Check candidate\r
2148 //\r
2149 if (*LineBuffer != ' ') {\r
2150 return (UINTN)-1;\r
2151 }\r
2152\r
2153 //\r
2154 // Get Offset\r
2155 //\r
2156 if (*(LineBuffer + 2) != ' ') {\r
2157 if (*Offset == (UINTN)-1) {\r
2158 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 2, " ");\r
2159 *Offset = AsciiXtoi (FieldBuffer);\r
2160 PatchForAsciiStrTokenAfter (FieldBuffer, ' ');\r
2161 }\r
2162 }\r
2163\r
2164 //\r
2165 // 1. assembly instruction\r
2166 //\r
2167 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, ":");\r
2168 //\r
2169 // 2. file path\r
2170 //\r
2171 FieldBuffer = AsciiStrGetNextTokenField (":");\r
2172 PatchForAsciiStrTokenBefore (FieldBuffer, ':');\r
2173 if (FieldBuffer == NULL) {\r
2174 //\r
2175 // candidate found\r
2176 //\r
2177 LineNumber = 0;\r
2178 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2179 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2180 continue;\r
2181 }\r
2182 //\r
2183 // 3. line number\r
2184 //\r
2185 FieldBuffer = AsciiStrGetNextTokenField (":");\r
2186 PatchForAsciiStrTokenBefore (FieldBuffer, ':');\r
2187 if (FieldBuffer == NULL) {\r
2188 //\r
2189 // impossible, TBD?\r
2190 //\r
2191 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2192 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2193 continue;\r
2194 }\r
2195\r
2196 LineNumber = AsciiAtoi (FieldBuffer);\r
2197 //\r
2198 // Not patch after\r
2199 //\r
2200\r
2201 return LineNumber;\r
2202 }\r
2203\r
2204 return (UINTN)-1;\r
2205}\r
2206\r
2207typedef enum {\r
2208 EdbEbcLineSearchTypeAny,\r
2209 EdbEbcLineSearchTypeFirst,\r
2210 EdbEbcLineSearchTypeLast,\r
2211 EdbEbcLineSearchTypeMax,\r
2212} EDB_EBC_LINE_SEARCH_TYPE;\r
2213\r
2214UINTN\r
2215EdbGetLineNumberFromCode (\r
2216 IN EFI_DEBUGGER_SYMBOL_ENTRY *Entry,\r
2217 IN UINTN FuncOffset,\r
2218 IN EDB_EBC_LINE_SEARCH_TYPE SearchType\r
2219 )\r
2220/*++\r
2221\r
2222Routine Description:\r
2223\r
2224 Get line number from this code file\r
2225\r
2226Arguments:\r
2227\r
2228 Entry - Symbol entry\r
2229 FuncOffset - Offset to functin entry\r
2230 SearchType - Search type for the code\r
2231\r
2232Returns:\r
2233\r
2234 Line number\r
2235\r
2236--*/\r
2237{\r
2238 CHAR8 *LineBuffer;\r
2239 UINTN LineNumber;\r
2240 UINTN Offset;\r
2241 UINTN CandidateLineNumber;\r
2242 UINTN CandidateOffset;\r
2243\r
2244 if (SearchType < 0 || SearchType >= EdbEbcLineSearchTypeMax) {\r
2245 return (UINTN)-1;\r
2246 }\r
2247\r
2248 LineNumber = (UINTN)-1;\r
2249 CandidateLineNumber = (UINTN)-1;\r
2250 CandidateOffset = (UINTN)-1;\r
2251 LineBuffer = AsciiStrGetNewTokenLine (Entry->CodBuffer, "\n");\r
2252 while (LineBuffer != NULL) {\r
2253 if (*LineBuffer != ' ') {\r
2254 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2255 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2256 continue;\r
2257 }\r
2258\r
2259 //\r
2260 // Get Info\r
2261 //\r
2262 LineNumber = EdbGetLineNumberAndOffsetFromThisLine (LineBuffer, &Offset);\r
2263\r
2264 //\r
2265 // Check offset\r
2266 //\r
2267 if (Offset != FuncOffset) {\r
2268 //\r
2269 // Check last offset match\r
2270 //\r
2271 if (CandidateOffset == FuncOffset) {\r
2272 if (SearchType == EdbEbcLineSearchTypeLast) {\r
2273 PatchForAsciiStrTokenAfter (LineBuffer, '\n');\r
2274 if (CandidateLineNumber != LineNumber) {\r
2275 return CandidateLineNumber;\r
2276 } else {\r
2277 return (UINTN)-1;\r
2278 }\r
2279 } else {\r
2280 //\r
2281 // impossible, TBD?\r
2282 //\r
2283 }\r
2284 }\r
2285\r
2286 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2287 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2288 CandidateLineNumber = LineNumber;\r
2289 continue;\r
2290 }\r
2291\r
2292 //\r
2293 // Offset match, more check\r
2294 //\r
2295 if (SearchType == EdbEbcLineSearchTypeAny) {\r
2296 PatchForAsciiStrTokenAfter (LineBuffer, '\n');\r
2297 return LineNumber;\r
2298 }\r
2299\r
2300 if (SearchType == EdbEbcLineSearchTypeFirst) {\r
2301 //\r
2302 // Check last line\r
2303 //\r
2304 PatchForAsciiStrTokenAfter (LineBuffer, '\n');\r
2305 if (CandidateLineNumber != LineNumber) {\r
2306 return LineNumber;\r
2307 } else {\r
2308 return (UINTN)-1;\r
2309 }\r
2310 }\r
2311\r
2312 CandidateLineNumber = LineNumber;\r
2313 CandidateOffset = Offset;\r
2314\r
2315 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2316 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2317 }\r
2318\r
2319 //\r
2320 // Check last offset match\r
2321 //\r
2322 if (CandidateOffset == FuncOffset) {\r
2323 if (SearchType == EdbEbcLineSearchTypeLast) {\r
2324 return CandidateLineNumber;\r
2325 }\r
2326 }\r
2327\r
2328 return (UINTN)-1;\r
2329}\r
2330\r
2331VOID *\r
2332EdbGetSourceStrFromCodeByLine (\r
2333 IN EFI_DEBUGGER_SYMBOL_ENTRY *Entry,\r
2334 IN UINTN LineNumber,\r
2335 IN VOID **FuncEnd\r
2336 )\r
2337/*++\r
2338\r
2339Routine Description:\r
2340\r
2341 Get the source string from this code file by line\r
2342\r
2343Arguments:\r
2344\r
2345 Entry - Symbol entry\r
2346 LineNumber - line number\r
2347 FuncEnd - Function end\r
2348\r
2349Returns:\r
2350\r
2351 Funtion start\r
2352\r
2353--*/\r
2354{\r
2355 CHAR8 *LineBuffer;\r
2356 CHAR8 *FieldBuffer;\r
2357 VOID *FuncStart;\r
2358 UINTN Number;\r
2359\r
2360 FuncStart = NULL;\r
2361 LineBuffer = AsciiStrGetNewTokenLine (Entry->CodBuffer, "\n");\r
2362 while (LineBuffer != NULL) {\r
2363 if (*LineBuffer != ';') {\r
2364 if (FuncStart != NULL) {\r
2365 //\r
2366 // Over\r
2367 //\r
2368 *FuncEnd = LineBuffer - 1;\r
2369 PatchForAsciiStrTokenAfter (LineBuffer, '\n');\r
2370 return FuncStart;\r
2371 }\r
2372 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2373 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2374 continue;\r
2375 }\r
2376\r
2377 //\r
2378 // Check LineNumber\r
2379 //\r
2380 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 1, " ");\r
2381 Number = AsciiAtoi (FieldBuffer);\r
2382 PatchForAsciiStrTokenAfter (FieldBuffer, ' ');\r
2383 if (Number != LineNumber) {\r
2384 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2385 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2386 continue;\r
2387 }\r
2388\r
2389 //\r
2390 // Line match, get line number\r
2391 //\r
2392 if (FuncStart == NULL) {\r
2393 FuncStart = LineBuffer;\r
2394 }\r
2395\r
2396 LineBuffer = AsciiStrGetNextTokenLine ("\n");\r
2397 PatchForAsciiStrTokenBefore (LineBuffer, '\n');\r
2398 }\r
2399\r
2400 return NULL;\r
2401}\r
2402\r
2403VOID *\r
2404EdbGetSourceStrFromCode (\r
2405 IN EFI_DEBUGGER_SYMBOL_ENTRY *Entry,\r
2406 IN UINTN FuncOffset,\r
2407 IN VOID **FuncEnd\r
2408 )\r
2409/*++\r
2410\r
2411Routine Description:\r
2412\r
2413 Get source string from this code file\r
2414\r
2415Arguments:\r
2416\r
2417 Entry - Symbol entry\r
2418 FuncOffset - Offset to functin entry\r
2419 FuncEnd - Function end\r
2420\r
2421Returns:\r
2422\r
2423 Funtion start\r
2424\r
2425--*/\r
2426{\r
2427 UINTN LineNumber;\r
2428\r
2429 //\r
2430 // Only search the last line, then display\r
2431 //\r
2432 LineNumber = EdbGetLineNumberFromCode (Entry, FuncOffset, EdbEbcLineSearchTypeLast);\r
2433 if (LineNumber == (UINTN)-1) {\r
2434 return NULL;\r
2435 }\r
2436\r
2437 return EdbGetSourceStrFromCodeByLine (Entry, LineNumber, FuncEnd);\r
2438}\r
2439\r
2440UINTN\r
2441EdbPrintSource (\r
2442 IN UINTN Address,\r
2443 IN BOOLEAN IsPrint\r
2444 )\r
2445/*++\r
2446\r
2447Routine Description:\r
2448\r
2449 Print source\r
2450\r
2451Arguments:\r
2452\r
2453 Address - Instruction address\r
2454 IsPrint - Whether need to print\r
2455\r
2456Returns:\r
2457\r
2458 1 - find the source\r
2459 0 - not find the source\r
2460\r
2461--*/\r
2462{\r
2463 UINTN SymbolAddress;\r
2464 EFI_DEBUGGER_SYMBOL_OBJECT *RetObject;\r
2465 EFI_DEBUGGER_SYMBOL_ENTRY *RetEntry;\r
2466 UINTN FuncOffset;\r
2467 UINT8 *FuncStart;\r
2468 UINT8 *FuncEnd;\r
2469 UINT8 *FuncIndex;\r
2470 CHAR8 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];\r
2471 UINTN BufferSize;\r
2472\r
2473 //\r
2474 // need we display symbol\r
2475 //\r
2476 if (!mDebuggerPrivate.DebuggerSymbolContext.DisplaySymbol) {\r
2477 return 0 ;\r
2478 }\r
2479\r
2480 //\r
2481 // find the symbol address\r
2482 //\r
2483 SymbolAddress = EbdFindSymbolAddress (\r
2484 Address,\r
2485 EdbMatchSymbolTypeLowerAddress,\r
2486 &RetObject,\r
2487 &RetEntry\r
2488 );\r
2489 if (SymbolAddress == 0) {\r
2490 return 0 ;\r
2491 }\r
2492\r
2493 FuncOffset = Address - SymbolAddress + RetEntry->FuncOffsetBase;\r
2494\r
2495 //\r
2496 // Get Func String\r
2497 //\r
2498 FuncStart = EdbGetSourceStrFromCode (RetEntry, FuncOffset, (VOID**) &FuncEnd);\r
2499 if (FuncStart == NULL) {\r
2500 return 0 ;\r
2501 }\r
2502\r
2503 //\r
2504 // check whether need to real print\r
2505 //\r
2506 if (!IsPrint) {\r
2507 return 1;\r
2508 }\r
2509\r
2510 *(UINT8 *)FuncEnd = 0;\r
2511\r
2512 //\r
2513 // seperate buffer by \n, so that \r can be added.\r
2514 //\r
2515 FuncIndex = FuncStart;\r
2516 while (*FuncIndex != 0) {\r
2517 if (*FuncIndex == '\n') {\r
2518 if ((FuncIndex - FuncStart) < (EFI_DEBUG_MAX_PRINT_BUFFER - 3)) {\r
2519 BufferSize = FuncIndex - FuncStart;\r
2520 } else {\r
2521 BufferSize = EFI_DEBUG_MAX_PRINT_BUFFER - 3;\r
2522 }\r
2523 if (BufferSize != 0) {\r
2524 CopyMem (Buffer, FuncStart, BufferSize);\r
2525 }\r
2526 Buffer[BufferSize] = 0;\r
2527 EDBPrint (L"%a\n", Buffer);\r
2528 FuncStart = FuncIndex + 1;\r
2529 FuncIndex = FuncStart;\r
2530 } else {\r
2531 FuncIndex ++;\r
2532 }\r
2533 }\r
2534\r
2535 //\r
2536 // Patch the end\r
2537 //\r
2538 *(UINT8 *)FuncEnd = '\n';\r
2539\r
2540 return 1 ;\r
2541}\r
2542\r
2543VOID\r
2544GetMapfileAndSymbol (\r
2545 IN CHAR16 *Symbol,\r
2546 OUT CHAR16 **MapfileName,\r
2547 OUT CHAR16 **SymbolName\r
2548 )\r
2549/*++\r
2550\r
2551Routine Description:\r
2552\r
2553 Get Mapfile and SymbolName from one symbol format: [MapFileName:]SymbolName\r
2554\r
2555Arguments:\r
2556\r
2557 Symbol - whole Symbol name\r
2558 MapfileName - the mapfile name in the symbol\r
2559 SymbolName - the symbol name in the symbol\r
2560\r
2561Returns:\r
2562\r
2563 None\r
2564\r
2565--*/\r
2566{\r
2567 CHAR16 *Ch;\r
2568\r
2569 *MapfileName = NULL;\r
2570 *SymbolName = Symbol;\r
2571\r
2572 for (Ch = Symbol; *Ch != 0; Ch++) {\r
2573 //\r
2574 // Find split char\r
2575 //\r
2576 if (*Ch == L':') {\r
2577 *MapfileName = Symbol;\r
2578 *Ch = 0;\r
2579 *SymbolName = Ch + 1;\r
2580 break;\r
2581 }\r
2582 }\r
2583\r
2584 return ;\r
2585}\r
2586\r
2587EFI_STATUS\r
2588Symboltoi (\r
2589 IN CHAR16 *Symbol,\r
2590 OUT UINTN *Address\r
2591 )\r
2592/*++\r
2593\r
2594Routine Description:\r
2595\r
2596 Convert a symbol to an address\r
2597\r
2598Arguments:\r
2599\r
2600 Symbol - Symbol name\r
2601 Address - Symbol address\r
2602\r
2603Returns:\r
2604\r
2605 EFI_SUCCESS - symbol found and address returned.\r
2606 EFI_NOT_FOUND - symbol not found\r
2607 EFI_NO_MAPPING - duplicated symbol not found\r
2608\r
2609--*/\r
2610{\r
2611 UINTN ObjectIndex;\r
2612 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
2613 UINTN EntryIndex;\r
2614 EFI_DEBUGGER_SYMBOL_ENTRY *Entry;\r
2615 CHAR16 *SymbolName;\r
2616 CHAR16 *MapfileName;\r
2617\r
2618 //\r
2619 // Split one symbol to mapfile name and symbol name\r
2620 //\r
2621 GetMapfileAndSymbol (Symbol, &MapfileName, &SymbolName);\r
2622\r
2623 *Address = 0;\r
2624 //\r
2625 // Go through each object\r
2626 //\r
2627 Object = mDebuggerPrivate.DebuggerSymbolContext.Object;\r
2628 for (ObjectIndex = 0; ObjectIndex < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; ObjectIndex++) {\r
2629 //\r
2630 // Check MapfileName\r
2631 //\r
2632 if ((MapfileName != NULL) && (StriCmp (Object[ObjectIndex].Name, MapfileName) != 0)) {\r
2633 continue;\r
2634 }\r
2635 //\r
2636 // Go through each entry\r
2637 //\r
2638 Entry = Object[ObjectIndex].Entry;\r
2639 for (EntryIndex = 0; EntryIndex < Object[ObjectIndex].EntryCount; EntryIndex++) {\r
2640 //\r
2641 // Check SymbolName (case sensitive)\r
2642 //\r
2643 if (StrCmpUnicodeAndAscii (SymbolName, Entry[EntryIndex].Name) == 0) {\r
2644 if ((*Address != 0) && (MapfileName == NULL)) {\r
2645 //\r
2646 // Find the duplicated symbol\r
2647 //\r
2648 EDBPrint (L"Duplicated Symbol found!\n");\r
2649 return EFI_NO_MAPPING;\r
2650 } else {\r
2651 //\r
2652 // record Address\r
2653 //\r
2654 *Address = (Entry[EntryIndex].RVA + Object[ObjectIndex].BaseAddress);\r
2655 }\r
2656 }\r
2657 }\r
2658 }\r
2659\r
2660 if (*Address == 0) {\r
2661 //\r
2662 // Not found\r
2663 //\r
2664 return EFI_NOT_FOUND;\r
2665 }\r
2666\r
2667 return EFI_SUCCESS;\r
2668}\r