8713976da0ef12b754481ea5f6a82e10d996dffb
[reactos.git] / reactos / apps / utils / pice / module / symbols.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module ModuleName:
6
7 symbols.c
8
9 Abstract:
10
11 Environment:
12
13 Kernel mode only
14
15 Author:
16
17 Klaus P. Gerlicher
18 Reactos Port by Eugene Ingerman
19
20 Revision History:
21
22 19-Aug-1998: created
23 15-Nov-2000: general cleanup of source files
24
25 Copyright notice:
26
27 This file may be distributed under the terms of the GNU Public License.
28
29 --*/
30
31 ////////////////////////////////////////////////////
32 // INCLUDES
33 ////
34 #include "remods.h"
35 #include "precomp.h"
36 #include "stab_gnu.h"
37
38 #include <ntdll/ldr.h>
39 #include <ntdll/rtl.h>
40 #include <internal/ps.h>
41 #include <internal/ob.h>
42 #include <internal/module.h>
43
44 #define NDEBUG
45 #include <debug.h>
46
47
48 PVOID pExports=0;
49 ULONG ulExportLen=0;
50
51 LOCAL_VARIABLE local_vars[512];
52
53 PICE_SYMBOLFILE_HEADER* apSymbols[32]={NULL,};
54 ULONG ulNumSymbolsLoaded=0;
55
56 ULONG kernel_end=0;
57
58 char tempSym[1024]; // temp buffer for output
59
60
61 PULONG LocalRegs[]=
62 {
63 &CurrentEAX,
64 &CurrentECX,
65 &CurrentEDX,
66 &CurrentEBX,
67 &CurrentESP,
68 &CurrentEBP,
69 &CurrentESI,
70 &CurrentEDI,
71 &CurrentEIP,
72 &CurrentEFL
73 };
74
75 typedef struct _VRET
76 {
77 ULONG value;
78 ULONG type;
79 ULONG father_type;
80 ULONG error;
81 ULONG file;
82 ULONG size;
83 ULONG address;
84 char name[256];
85 char type_name[256];
86 BOOLEAN bPtrType;
87 BOOLEAN bStructType;
88 BOOLEAN bArrayType;
89 PICE_SYMBOLFILE_HEADER* pSymbols;
90 }VRET,*PVRET;
91
92 ULONG ulIndex;
93 LPSTR pExpression;
94 VRET vr;
95 VRET vrStructMembers[1024];
96 ULONG ulNumStructMembers;
97
98 BOOLEAN Expression(PVRET pvr);
99
100 LIST_ENTRY *pModuleListHead = NULL;
101 extern PDIRECTORY_OBJECT *pNameSpaceRoot;
102 extern PDEBUG_MODULE pdebug_module_tail;
103 extern PDEBUG_MODULE pdebug_module_head;
104
105
106 PVOID HEADER_TO_BODY(POBJECT_HEADER obj)
107 {
108 return(((void *)obj)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER));
109 }
110
111 POBJECT_HEADER BODY_TO_HEADER(PVOID body)
112 {
113 PCOMMON_BODY_HEADER chdr = (PCOMMON_BODY_HEADER)body;
114 return(CONTAINING_RECORD((&(chdr->Type)),OBJECT_HEADER,Type));
115 }
116
117 /*-----------------12/26/2001 7:59PM----------------
118 * FreeModuleList - free list allocated with InitModuleList. Must
119 * be called at passive irql.
120 * --------------------------------------------------*/
121 VOID FreeModuleList( PDEBUG_MODULE pm )
122 {
123 PDEBUG_MODULE pNext = pm;
124
125 ENTER_FUNC();
126
127 while( pNext ){
128 pNext = pm->next;
129 ExFreePool( pm );
130 }
131 LEAVE_FUNC();
132 }
133
134 /*-----------------12/26/2001 7:58PM----------------
135 * InitModuleList - creates linked list of length len for debugger. Can't be
136 * called at elevated IRQL
137 * --------------------------------------------------*/
138 BOOLEAN InitModuleList( PDEBUG_MODULE *ppmodule, ULONG len )
139 {
140 ULONG i;
141 PDEBUG_MODULE pNext = NULL, pm = *ppmodule;
142
143 ENTER_FUNC();
144
145 ASSERT(pm==NULL);
146
147 for(i=1;i<=len;i++){
148 pm = (PDEBUG_MODULE)ExAllocatePool( NonPagedPool, sizeof( DEBUG_MODULE ) );
149 if( !pm ){
150 FreeModuleList(pNext);
151 return FALSE;
152 }
153 pm->next = pNext;
154 pm->size = 0;
155 pm->BaseAddress = NULL;
156 //DbgPrint("len1: %d\n", pm->name.Length);
157 pNext = pm;
158 }
159 *ppmodule = pm;
160
161 LEAVE_FUNC();
162
163 return TRUE;
164 }
165
166 BOOLEAN ListUserModules( PPEB peb )
167 {
168 PLIST_ENTRY UserModuleListHead;
169 PLIST_ENTRY Entry;
170 PLDR_MODULE Module;
171 PPEB_LDR_DATA Ldr;
172
173 ENTER_FUNC();
174
175 Ldr = peb->Ldr;
176 if( Ldr && IsAddressValid((ULONG)Ldr)){
177 UserModuleListHead = &Ldr->InLoadOrderModuleList;
178 ASSERT(IsAddressValid((ULONG)UserModuleListHead));
179 Entry = UserModuleListHead->Flink;
180 while (Entry != UserModuleListHead)
181 {
182 Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
183 //DbgPrint("Module: %x, BaseAddress: %x\n", Module, Module->BaseAddress);
184
185 DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x, BaseAddress: %x\n", Module->FullDllName.Buffer,
186 Module->BaseDllName.Buffer, Module->SizeOfImage, Module->EntryPoint, Module->BaseAddress ));
187
188 pdebug_module_tail->size = Module->SizeOfImage;
189 pdebug_module_tail->BaseAddress = Module->BaseAddress;
190 pdebug_module_tail->EntryPoint = (PVOID)(Module->EntryPoint);
191 ASSERT(Module->BaseDllName.Length<DEBUG_MODULE_NAME_LEN); //name length is limited
192 PICE_wcscpy( pdebug_module_tail->name, Module->BaseDllName.Buffer );
193 pdebug_module_tail = pdebug_module_tail->next;
194
195 Entry = Entry->Flink;
196 }
197 }
198 LEAVE_FUNC();
199 return TRUE;
200 }
201
202 POBJECT FindDriverObjectDirectory( void )
203 {
204 PLIST_ENTRY current;
205 POBJECT_HEADER current_obj;
206 PDIRECTORY_OBJECT pd;
207
208 ENTER_FUNC();
209
210 if( pNameSpaceRoot && *pNameSpaceRoot ){
211 current = (*pNameSpaceRoot)->head.Flink;
212 while (current!=(&((*pNameSpaceRoot)->head)))
213 {
214 current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
215 DPRINT((0,"Scanning %S\n",current_obj->Name.Buffer));
216 if (_wcsicmp(current_obj->Name.Buffer, L"Modules")==0)
217 {
218 pd=HEADER_TO_BODY(current_obj);
219 DPRINT((0,"Found it %x\n",pd));
220 return pd;
221 }
222 current = current->Flink;
223 }
224 }
225 LEAVE_FUNC();
226 return NULL;
227 }
228
229 BOOLEAN ListDriverModules( void )
230 {
231 PLIST_ENTRY current_entry;
232 PMODULE_OBJECT current;
233 POBJECT_HEADER current_obj;
234
235 ENTER_FUNC();
236
237 ASSERT( pModuleListHead );
238
239 current_entry = pModuleListHead->Flink;
240
241 while (current_entry != (pModuleListHead)){
242
243 current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry);
244
245 DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x\n", current->FullName.Buffer,
246 current->BaseName.Buffer, current->Length, current->EntryPoint ));
247
248 pdebug_module_tail->BaseAddress = current->Base;
249 pdebug_module_tail->size = current->Length;
250 PICE_wcscpy( pdebug_module_tail->name, current->BaseName.Buffer);
251 pdebug_module_tail->EntryPoint = current->EntryPoint;
252
253 pdebug_module_tail = pdebug_module_tail->next;
254
255 if (current && _wcsicmp(current->BaseName.Buffer, L"ntoskrnl")==0)
256 {
257 kernel_end = (ULONG)current->Base + current->Length;
258 }
259 current_entry = current_entry->Flink;
260 }
261
262 LEAVE_FUNC();
263 return TRUE;
264 }
265
266 BOOLEAN BuildModuleList( void )
267 {
268 PPEB peb;
269 PEPROCESS tsk;
270 ENTER_FUNC();
271
272 pdebug_module_tail = pdebug_module_head;
273 tsk = IoGetCurrentProcess();
274 ASSERT(IsAddressValid((ULONG)tsk));
275 if( tsk ){
276 peb = tsk->Peb;
277 if( peb ){
278 if( !ListUserModules( peb ) ){
279 LEAVE_FUNC();
280 return FALSE;
281 }
282 }
283 }
284 if( !ListDriverModules() ){
285 LEAVE_FUNC();
286 return FALSE;
287 }
288 LEAVE_FUNC();
289 return TRUE;
290 }
291
292 //*************************************************************************
293 // IsModuleLoaded()
294 //
295 //*************************************************************************
296 PDEBUG_MODULE IsModuleLoaded(LPSTR p)
297 {
298 PDEBUG_MODULE pd;
299
300 ENTER_FUNC();
301 DPRINT((0,"IsModuleLoaded(%s)\n",p));
302
303 if(BuildModuleList())
304 {
305 pd = pdebug_module_head;
306 do
307 {
308 char temp[DEBUG_MODULE_NAME_LEN];
309 DPRINT((0,"module (%x) %S\n",pd->size,pd->name));
310 CopyWideToAnsi(temp,pd->name);
311 if(pd->size && PICE_strcmpi(p,temp) == 0)
312 {
313 DPRINT((0,"module %S is loaded!\n",pd->name));
314 LEAVE_FUNC();
315 return pd;
316 }
317 }while((pd = pd->next)!=pdebug_module_tail);
318 }
319 LEAVE_FUNC();
320 return NULL;
321 }
322
323 //*************************************************************************
324 // ScanExports()
325 //
326 //*************************************************************************
327 BOOLEAN ScanExports(const char *pFind,PULONG pValue)
328 {
329 char temp[256];
330 LPSTR pStr=NULL;
331 LPSTR pExp = pExports;
332 BOOLEAN bResult = FALSE;
333
334 ENTER_FUNC();
335 DPRINT((0,"ScanExports pValue: %x\n", pValue));
336 nomatch:
337 if(pExports)
338 pStr = strstr(pExp,pFind);
339
340 if(pStr)
341 {
342 LPSTR p;
343 ULONG state;
344 LPSTR pOldStr = pStr;
345
346 for(;(*pStr!=0x0a && *pStr!=0x0d) && (ULONG)pStr>=(ULONG)pExports;pStr--);
347 pStr++;
348 p = temp;
349 for(;(*pStr!=0x0a && *pStr!=0x0d);)*p++=*pStr++;
350 *p=0;
351 p = (LPSTR) PICE_strtok(temp," ");
352 state=0;
353 while(p)
354 {
355 switch(state)
356 {
357 case 0:
358 ConvertTokenToHex(p,pValue);
359 break;
360 case 1:
361 break;
362 case 2:
363 if(strcmp(p,pFind)!=0)
364 {
365 DPRINT((0,"Not: %s\n", p));
366 pExp = pOldStr+1;
367 goto nomatch;
368 }
369 state = -1;
370 bResult = TRUE;
371 DPRINT((0,"%s @ %x\n",pFind,*pValue));
372 goto exit;
373 break;
374 }
375 state++;
376 p = (char*) PICE_strtok(NULL," ");
377 }
378 }
379 exit:
380 DPRINT((0,"%s %x @ %x\n",pFind,pValue,*pValue));
381
382 LEAVE_FUNC();
383
384 return bResult;
385 }
386
387 //*************************************************************************
388 // ReadHex()
389 //
390 //*************************************************************************
391 BOOLEAN ReadHex(LPSTR p,PULONG pValue)
392 {
393 ULONG result=0,i;
394
395 for(i=0;i<8 && p[i]!=0 && p[i]!=' ';i++)
396 {
397 if(p[i]>='0' && p[i]<='9')
398 {
399 result<<=4;
400 result|=(ULONG)(UCHAR)(p[i]-'0');
401 }
402 else if(p[i]>='A' && p[i]<='F')
403 {
404 result<<=4;
405 result|=(ULONG)(UCHAR)(p[i]-'A'+10);
406 }
407 else if(p[i]>='a' && p[i]<='f')
408 {
409 result<<=4;
410 result|=(ULONG)(UCHAR)(p[i]-'a'+10);
411 }
412 else
413 return FALSE;
414 }
415
416 *pValue = result;
417 return TRUE;
418 }
419
420 //*************************************************************************
421 // ScanExportLine()
422 //
423 //*************************************************************************
424 BOOLEAN ScanExportLine(LPSTR p,PULONG ulValue,LPSTR* ppPtrToSymbol)
425 {
426 BOOLEAN bResult = FALSE;
427
428 if(ReadHex(p,ulValue))
429 {
430 p += 11;
431 *ppPtrToSymbol += 11;
432 bResult = TRUE;
433 }
434
435 return bResult;
436 }
437
438 //*************************************************************************
439 // ValidityCheckSymbols()
440 //
441 //*************************************************************************
442 BOOLEAN ValidityCheckSymbols(PICE_SYMBOLFILE_HEADER* pSymbols)
443 {
444 BOOLEAN bRet;
445
446 DPRINT((0,"ValidityCheckSymbols()\n"));
447
448 bRet = (IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToHeaders,pSymbols->ulSizeOfHeader) &&
449 IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals) &&
450 IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToGlobalsStrings,pSymbols->ulSizeOfGlobalsStrings) &&
451 IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToStabs,pSymbols->ulSizeOfStabs) &&
452 IsRangeValid((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings,pSymbols->ulSizeOfStabsStrings));
453
454 DPRINT((0,"ValidityCheckSymbols(): symbols are %s\n",bRet?"VALID":"NOT VALID"));
455
456 return bRet;
457 }
458
459 //*************************************************************************
460 // FindModuleSymbols()
461 //
462 //*************************************************************************
463 PICE_SYMBOLFILE_HEADER* FindModuleSymbols(ULONG addr)
464 {
465 ULONG start,end,i;
466 PDEBUG_MODULE pd = pdebug_module_head;
467
468 DPRINT((0,"FindModuleSymbols(%x)\n",addr));
469 if(BuildModuleList())
470 {
471 i=0;
472 pd = pdebug_module_head;
473 do
474 {
475 DPRINT((0,"pd: %x\n", pd));
476 if(pd->size)
477 {
478 start = (ULONG)pd->BaseAddress;
479 end = start + pd->size;
480 DPRINT((0,"FindModuleSymbols(): %S %x-%x\n",pd->name,start,end));
481 if(addr>=start && addr<end)
482 {
483 DPRINT((0,"FindModuleSymbols(): address matches %S %x-%x\n",pd->name,start,end));
484 for(i=0;i<ulNumSymbolsLoaded;i++)
485 {
486 DPRINT((0,"%S -", apSymbols[i]->name ));
487 if(PICE_wcsicmp(pd->name,apSymbols[i]->name) == 0)
488 {
489 if(ValidityCheckSymbols(apSymbols[i]))
490 return apSymbols[i];
491 else
492 return NULL;
493 }
494 }
495 }
496 }
497 }while((pd = pd->next) != pdebug_module_tail);
498 }
499
500 return NULL;
501 }
502
503 //*************************************************************************
504 // FindModuleFromAddress()
505 //
506 //*************************************************************************
507 PDEBUG_MODULE FindModuleFromAddress(ULONG addr)
508 {
509 PDEBUG_MODULE pd;
510 ULONG start,end;
511
512 DPRINT((0,"FindModuleFromAddress()\n"));
513 if(BuildModuleList())
514 {
515 pd = pdebug_module_head;
516 do
517 {
518 if(pd->size)
519 {
520 start = (ULONG)pd->BaseAddress;
521 end = start + pd->size;
522 DPRINT((0,"FindModuleFromAddress(): %S %x-%x\n",pd->name,start,end));
523 if(addr>=start && addr<end)
524 {
525 DPRINT((0,"FindModuleFromAddress(): found %S\n",pd->name));
526 return pd;
527 }
528 }
529 }while((pd = pd->next)!=pdebug_module_tail);
530 }
531
532 return NULL;
533 }
534
535 //*************************************************************************
536 // FindModuleByName()
537 //
538 //*************************************************************************
539 PDEBUG_MODULE FindModuleByName(LPSTR modname)
540 {
541 PDEBUG_MODULE pd;
542 WCHAR tempstr[DEBUG_MODULE_NAME_LEN];
543
544 DPRINT((0,"FindModuleFromAddress()\n"));
545 if( !PICE_MultiByteToWideChar(CP_ACP, NULL, modname, -1, tempstr, DEBUG_MODULE_NAME_LEN ) )
546 {
547 DPRINT((0,"Can't convert module name.\n"));
548 return NULL;
549 }
550
551 if(BuildModuleList())
552 {
553 pd = pdebug_module_head;
554 do
555 {
556 if(pd->size)
557 {
558 if(PICE_wcsicmp(tempstr,pd->name) == 0)
559 {
560 DPRINT((0,"FindModuleByName(): found %S\n",pd->name));
561 return pd;
562 }
563 }
564 }while((pd = pd->next) != pdebug_module_tail);
565 }
566
567 return NULL;
568 }
569
570 //*************************************************************************
571 // FindModuleSymbolsByModuleName()
572 //
573 //*************************************************************************
574 PICE_SYMBOLFILE_HEADER* FindModuleSymbolsByModuleName(LPSTR modname)
575 {
576 ULONG i;
577 WCHAR tempstr[DEBUG_MODULE_NAME_LEN];
578
579 DPRINT((0,"FindModuleSymbols()\n"));
580 if( !PICE_MultiByteToWideChar(CP_ACP, NULL, modname, -1, tempstr, DEBUG_MODULE_NAME_LEN ) )
581 {
582 DPRINT((0,"Can't convert module name in FindModuleSymbols.\n"));
583 return NULL;
584 }
585
586 for(i=0;i<ulNumSymbolsLoaded;i++)
587 {
588 if(PICE_wcsicmp(tempstr,apSymbols[i]->name) == 0)
589 return apSymbols[i];
590 }
591
592 return NULL;
593 }
594
595 //*************************************************************************
596 // ScanExportsByAddress()
597 //
598 //*************************************************************************
599 BOOLEAN ScanExportsByAddress(LPSTR *pFind,ULONG ulValue)
600 {
601 char temp[256];
602 static char temp3[256];
603 LPSTR p,pStartOfLine,pSymbolName=NULL;
604 ULONG ulCurrentValue=0;
605 BOOLEAN bResult = FALSE;
606 PDEBUG_MODULE pd;
607 ULONG ulMinValue = -1;
608 PIMAGE_SYMBOL pSym,pSymEnd; //running pointer to symbols and end of sym talbe
609 PIMAGE_SYMBOL pFoundSym = NULL; //current best symbol match
610 ULONG ulAddr = 0x0; //address of the best match
611 LPSTR pStr;
612 PIMAGE_SECTION_HEADER pShdr;
613 PICE_SYMBOLFILE_HEADER* pSymbols;
614 ULONG ulSectionSize;
615 LPSTR pName;
616
617 ENTER_FUNC();
618 DPRINT((0,"In ScanExportsByAddress:\n"));
619
620 pSymbols = FindModuleSymbols(ulValue);
621 DPRINT((0,"pSymbols: %x\n", pSymbols));
622
623 if(BuildModuleList()){
624 if(pSymbols && pdebug_module_head)
625 {
626 PDEBUG_MODULE pdTemp;
627
628 DPRINT((0,"looking up symbols\n"));
629 pd = pdebug_module_head;
630 do
631 {
632 if(pd->size){
633 pdTemp = pd;
634
635 if(ulValue>=((ULONG)pdTemp->BaseAddress) && ulValue<((ULONG)pdTemp+pdTemp->size))
636 {
637 if(PICE_wcsicmp(pdTemp->name,pSymbols->name) == 0)
638 {
639 DPRINT((0,"ScanExportsByAddress(): found symbols for module %S @ %x \n",pdTemp->name,(ULONG)pSymbols));
640
641 pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
642 pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
643 pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
644 pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
645
646 if(!IsRangeValid((ULONG)pSym,sizeof(IMAGE_SYMBOL) ) ) //should we actually check all the symbols here?
647 {
648 DPRINT((0,"ScanExportsByAddress(): pSym = %x is not a valid pointer\n",(ULONG)pSym));
649 return FALSE;
650 }
651
652 DPRINT((0,"ScanExportsByAddress(): pSym = %x\n",pSym));
653 DPRINT((0,"ScanExportsByAddress(): pStr = %x\n",pStr));
654 DPRINT((0,"ScanExportsByAddress(): pShdr = %x\n",pShdr));
655
656 DPRINT((0,"ScanExportsByAddress(): %S has %u symbols\n",pSymbols->name,pSymbols->ulSizeOfGlobals/sizeof(IMAGE_SYMBOL)));
657
658 /* go through all the global symbols and find the one with
659 the largest address which is less than ulValue */
660 while(pSym < pSymEnd)
661 { //it seems only 0x0 and 0x20 are used for type and External or Static storage classes
662 if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
663 ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) || (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)) &&
664 (pSym->SectionNumber > 0 ))
665 {
666 ULONG ulCurrAddr;
667 PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
668
669
670 DPRINT((0,"ScanExportsByAddress(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
671
672 if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
673 {
674 DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
675 return FALSE;
676 }
677 //to get address in the memory we base address of the module and
678 //add offset of the section and then add offset of the symbol from
679 //the begining of the section
680 ulCurrAddr = ((ULONG)pdTemp->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
681 DPRINT((0,"ScanExportsByAddress(): CurrAddr [1] = %x\n",ulCurrAddr));
682
683 if(ulCurrAddr<=ulValue && ulCurrAddr>ulAddr)
684 {
685 ulAddr = ulCurrAddr;
686 pFoundSym = pSym;
687 }
688 }
689 //skip the auxiliary symbols and get the next symbol
690 pSym += pSym->NumberOfAuxSymbols + 1;
691 }
692 *pFind = temp3;
693 if( pFoundSym->N.Name.Short ){
694 pName = pFoundSym->N.ShortName; //name is in the header
695 PICE_sprintf(temp3,"%S!%.8s",pdTemp->name,pName); //if name is in the header it may be nonzero terminated
696 }
697 else{
698 ASSERT(pFoundSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
699 pName = pStr+pFoundSym->N.Name.Long;
700 if(!IsAddressValid((ULONG)pName))
701 {
702 DPRINT((0,"ScanExportsByAddress(): pName = %x is not a valid pointer\n",pName));
703 return FALSE;
704 }
705 PICE_sprintf(temp3,"%S!%s",pdTemp->name,pName);
706 }
707 DPRINT((0,"ScanExportsByAddress(): pName = %x\n",(ULONG)pName));
708 return TRUE;
709 }
710 }
711 }
712 }while((pd = pd->next));
713 }
714 }
715 // if haven't found in the symbols try ntoskrnl exports. (note: check that this is needed since we
716 // already checked ntoskrnl coff symbol table)
717 if(pExports && ulValue >= KERNEL_START && ulValue < kernel_end)
718 {
719 p = pExports;
720 // while we bound in System.map
721 while(p<((LPSTR)pExports+ulExportLen))
722 {
723 // make a temp ptr to the line we can change
724 pStartOfLine = p;
725 // will read the hex value and return a pointer to the symbol name
726 if(ScanExportLine(p,&ulCurrentValue,&pStartOfLine))
727 {
728 if(ulValue>=ulCurrentValue && (ulValue-ulCurrentValue)<ulMinValue)
729 {
730 // save away our info for later
731 ulMinValue = ulValue-ulCurrentValue;
732 pSymbolName = pStartOfLine;
733 bResult = TRUE;
734 *pFind = temp3;
735 if(ulMinValue==0)
736 break;
737 }
738 }
739 // increment pointer to next line
740 p = pStartOfLine;
741 while(*p!=0 && *p!=0x0a && *p!=0x0d)p++;
742 p++;
743 }
744 if(bResult)
745 {
746 int i;
747 // copy symbol name to temp string
748 for(i=0;pSymbolName[i]!=0 && pSymbolName[i]!=0x0a && pSymbolName[i]!=0x0d;i++)
749 temp[i] = pSymbolName[i];
750 temp[i] = 0;
751 // decide if we need to append an offset
752 if(ulMinValue)
753 PICE_sprintf(temp3,"ntoskrnl!%s+%.8X",temp,ulMinValue);
754 else
755 PICE_sprintf(temp3,"ntoskrnl!%s",temp);
756 }
757 }
758
759 LEAVE_FUNC();
760 return bResult;
761 }
762
763 //*************************************************************************
764 // FindFunctionByAddress()
765 //
766 //*************************************************************************
767 LPSTR FindFunctionByAddress(ULONG ulValue,PULONG pulstart,PULONG pulend)
768 {
769 PIMAGE_SYMBOL pSym, pSymEnd, pFoundSym;
770 LPSTR pStr;
771 PIMAGE_SECTION_HEADER pShdr;
772 PDEBUG_MODULE pd;
773 PDEBUG_MODULE pdTemp;
774 PICE_SYMBOLFILE_HEADER* pSymbols;
775 ULONG start,end;
776 static char temp4[256];
777 LPSTR pName;
778
779 pSymbols = FindModuleSymbols(ulValue);
780 DPRINT((0,"FindFunctionByAddress(): symbols for %S @ %x \n",pSymbols->name,(ULONG)pSymbols));
781 if(pSymbols && pdebug_module_head)
782 {
783 DPRINT((0,"looking up symbol\n"));
784 pd = pdebug_module_head;
785 do
786 {
787 ASSERT(pd->size);
788 pdTemp = pd;
789
790 //initial values for start and end.
791 start = (ULONG)pdTemp->BaseAddress;
792 end = start+pdTemp->size;
793
794 DPRINT((0,"FindFunctionByAddress(): ulValue %x\n",ulValue));
795
796 if(ulValue>=start && ulValue<end)
797 {
798 DPRINT((0,"FindFunctionByAddress(): address matches %S\n",(ULONG)pdTemp->name));
799 if(PICE_wcsicmp(pdTemp->name,pSymbols->name) == 0)
800 {
801 DPRINT((0,"found symbols for module %S\n",pdTemp->name));
802 pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
803 pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
804 pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
805 pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
806
807 if(!IsRangeValid((ULONG)pSym,sizeof(IMAGE_SYMBOL) ) ) //should we actually check all the symbols here?
808 {
809 DPRINT((0,"FindFunctionByAddress(): pSym = %x is not a valid pointer\n",(ULONG)pSym));
810 return FALSE;
811 }
812 DPRINT((0,"pSym = %x\n",pSym));
813 DPRINT((0,"pStr = %x\n",pStr));
814 DPRINT((0,"pShdr = %x\n",pShdr));
815
816 while( pSym < pSymEnd )
817 {
818 //symbol is a function is it's type is 0x20, and section>0
819 if(( (pSym->Type == 0x20) &&
820 (pSym->SectionNumber > 0 )))
821 {
822 ULONG ulCurrAddr;
823 PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
824
825 DPRINT((0,"FindFunctionByAddress(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
826
827 if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
828 {
829 DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
830 return FALSE;
831 }
832 //to get address in the memory we base address of the module and
833 //add offset of the section and then add offset of the symbol from
834 //the begining of the section
835 ulCurrAddr = ((ULONG)pdTemp->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
836 DPRINT((0,"FindFunctionByAddress(): CurrAddr [1] = %x\n",ulCurrAddr));
837 DPRINT((0,"%x ", ulCurrAddr));
838
839 if(ulCurrAddr<=ulValue && ulCurrAddr>start)
840 {
841 start = ulCurrAddr;
842 pFoundSym = pSym;
843 //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for start %x\n",start));
844 }
845 else if(ulCurrAddr>=ulValue && ulCurrAddr<end)
846 {
847 end = ulCurrAddr;
848 //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for end %x\n",end));
849 }
850 }
851 //skip the auxiliary symbols and get the next symbol
852 pSym += pSym->NumberOfAuxSymbols + 1;
853 }
854 //we went through all the symbols for this module
855 //now start should point to the start of the function and
856 //end to the start of the next (or end of section)
857 if(pulstart)
858 *pulstart = start;
859
860 if(pulend){
861 //just in case there is more than one code section
862 PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pFoundSym->SectionNumber-1);
863 if( end > (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData ){
864 DPRINT((0,"Hmm: end=%d, end of section: %d\n", end, (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData));
865 end = (ULONG)pdTemp->BaseAddress+pShdrThis->SizeOfRawData;
866 }
867 *pulend = end;
868 }
869
870 if(pFoundSym->N.Name.Short){
871 //name is in the header. it's not zero terminated. have to copy.
872 PICE_sprintf(temp4,"%.8s", pFoundSym->N.ShortName);
873 pName = temp4;
874 DPRINT((0,"Function name: %S!%.8s",pdTemp->name,pName));
875 }
876 else{
877 ASSERT(pFoundSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
878 pName = pStr+pFoundSym->N.Name.Long;
879 if(!IsAddressValid((ULONG)pName))
880 {
881 DPRINT((0,"FindFunctionByAddress(): pName = %x is not a valid pointer\n",pName));
882 return NULL;
883 }
884 DPRINT((0,"Function name: %S!%s",pdTemp->name,pName));
885 }
886 return pName;
887 }
888 }
889 }while((pd = pd->next) != pdebug_module_tail);
890 }
891 return NULL;
892 }
893
894 //*************************************************************************
895 // FindDataSectionOffset()
896 //
897 //*************************************************************************
898 /* ei: never used
899 ULONG FindDataSectionOffset(Elf32_Shdr* pSHdr)
900 {
901
902 DPRINT((0,"FindDataSectionOffset()\n"));
903
904 while(1)
905 {
906 DPRINT((0,"FindDataSectionOffset(): sh_offset %.8X sh_addr = %.8X\n",pSHdr->sh_offset,pSHdr->sh_addr));
907 if((pSHdr->sh_flags & (SHF_WRITE|SHF_ALLOC) ) == (SHF_WRITE|SHF_ALLOC))
908 {
909
910 return pSHdr->sh_offset;
911 }
912 pSHdr++;
913 }
914
915 return 0;
916 }
917 */
918
919 //*************************************************************************
920 // FindFunctionInModuleByNameViaKsyms()
921 //
922 //*************************************************************************
923 /* ei: not needed. no Ksyms!
924 ULONG FindFunctionInModuleByNameViaKsyms(struct module* pMod,LPSTR szFunctionname)
925 {
926 ULONG i;
927
928 ENTER_FUNC();
929
930 if(pMod->nsyms)
931 {
932 DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %u symbols for module %s\n",pMod->nsyms,pMod->name));
933 for(i=0;i<pMod->nsyms;i++)
934 {
935 DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %s\n",pMod->syms[i].name));
936 if(PICE_strcmpi((LPSTR)pMod->syms[i].name,szFunctionname) == 0)
937 {
938 DPRINT((0,"FindFunctionInModuleByName(): symbol was in exports\n"));
939 LEAVE_FUNC();
940 return pMod->syms[i].value;
941 }
942 }
943 }
944
945 DPRINT((0,"FindFunctionInModuleByName(): symbol wasn't in exports\n"));
946 LEAVE_FUNC();
947 return 0;
948 }
949 */
950
951 //*************************************************************************
952 // FindFunctionInModuleByName()
953 //
954 //*************************************************************************
955 ULONG FindFunctionInModuleByName(LPSTR szFunctionname, PDEBUG_MODULE pd)
956 {
957 ULONG i,addr;
958 PICE_SYMBOLFILE_HEADER* pSymbols=NULL;
959 PIMAGE_SYMBOL pSym, pSymEnd;
960 LPSTR pStr;
961 PIMAGE_SECTION_HEADER pShdr;
962
963 ENTER_FUNC();
964 DPRINT((0,"FindFunctionInModuleByName(%s)\n",szFunctionname));
965 DPRINT((0,"FindFunctionInModuleByName(): mod size = %x\n",pd->size));
966 DPRINT((0,"FindFunctionInModuleByName(): module is %S\n",pd->name));
967
968 addr = (ULONG)pd->BaseAddress;
969
970 pSymbols = FindModuleSymbols(addr);
971 if(pSymbols)
972 {
973 DPRINT((0,"FindFunctionInModuleByName(): found symbol table for %S\n",pSymbols->name));
974 pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
975 pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
976 pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
977 pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
978
979 while( pSym < pSymEnd )
980 {
981 //symbol is a function is it's type is 0x20, storage class is external and section>0
982 //if(( (pSym->Type == 0x20) && (pSym->StorageClass==IMAGE_SYM_CLASS_EXTERNAL) &&
983 // (pSym->SectionNumber > 0 )))
984
985 if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
986 ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) || (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)) &&
987 (pSym->SectionNumber > 0 ))
988
989 {
990 ULONG start;
991 LPSTR pName;
992 PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
993
994 start = ((ULONG)pd->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
995 DPRINT((0,"FindFunctionInModuleByName(): %s @ %x\n",szFunctionname,start));
996
997 if(pSym->N.Name.Short){ //if name is stored in the structure
998 //name may be not zero terminated but 8 characters max
999 DPRINT((0,"FindFunctionInModuleByName: %.8s\n", pSym->N.ShortName));
1000 pName = pSym->N.ShortName; //name is in the header
1001 if((PICE_fnncmp(pName,szFunctionname, 8) == 0) && start)
1002 {
1003 DPRINT((0,"FindFunctionInModuleByName(): symbol was in symbol table, start: %x\n", start));
1004 LEAVE_FUNC();
1005 return start;
1006 }
1007 }else{
1008 pName = pStr+pSym->N.Name.Long;
1009 DPRINT((0,"FindFunctionInModuleByName: %s\n", pName));
1010 if((PICE_fncmp(pName,szFunctionname) == 0) && start)
1011 {
1012 DPRINT((0,"FindFunctionInModuleByName(): symbol was in string table, start: %x\n", start));
1013 LEAVE_FUNC();
1014 return start;
1015 }
1016 }
1017 }
1018 //skip the auxiliary symbols and get the next symbol
1019 pSym += pSym->NumberOfAuxSymbols + 1;
1020 }
1021 }
1022 LEAVE_FUNC();
1023 return 0;
1024 }
1025
1026 //*************************************************************************
1027 // ExtractTypeNumber()
1028 //
1029 //*************************************************************************
1030 ULONG ExtractTypeNumber(LPSTR p)
1031 {
1032 LPSTR pTypeNumber;
1033 ULONG ulTypeNumber = 0;
1034
1035 DPRINT((0,"ExtractTypeNumber(%s)\n",p));
1036
1037 pTypeNumber = PICE_strchr(p,'(');
1038
1039 if(pTypeNumber)
1040 {
1041 pTypeNumber++;
1042 ulTypeNumber = ExtractNumber(pTypeNumber);
1043 ulTypeNumber <<= 16;
1044 pTypeNumber = PICE_strchr(p,',');
1045 if(pTypeNumber)
1046 {
1047 pTypeNumber++;
1048 ulTypeNumber += ExtractNumber(pTypeNumber);
1049 }
1050 else
1051 {
1052 ulTypeNumber = 0;
1053 }
1054 }
1055 return ulTypeNumber;
1056 }
1057
1058 //*************************************************************************
1059 // FindTypeDefinitionForCombinedTypes()
1060 //
1061 //*************************************************************************
1062 LPSTR FindTypeDefinitionForCombinedTypes(PICE_SYMBOLFILE_HEADER* pSymbols,ULONG ulTypeNumber,ULONG ulFileNumber)
1063 {
1064 ULONG i;
1065 PSTAB_ENTRY pStab;
1066 LPSTR pStr,pName,pTypeNumber,pTypeDefIncluded,pNameTemp;
1067 int nStabLen;
1068 int nOffset=0,nNextOffset=0,nLen;
1069 static char szAccumulatedName[2048];
1070 ULONG ulCurrentTypeNumber,ulCurrentFileNumber=0;
1071 static char szCurrentPath[256];
1072
1073 ENTER_FUNC();
1074
1075 *szAccumulatedName = 0;
1076
1077 pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
1078 nStabLen = pSymbols->ulSizeOfStabs;
1079 pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
1080
1081 DPRINT((0,"FindTypeDefinitionForCombinedTypes()\n"));
1082
1083 for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
1084 {
1085 pName = &pStr[pStab->n_strx + nOffset];
1086
1087 switch(pStab->n_type)
1088 {
1089 case N_UNDF:
1090 nOffset += nNextOffset;
1091 nNextOffset = pStab->n_value;
1092 break;
1093 case N_SO:
1094 if((nLen = PICE_strlen(pName)))
1095 {
1096 if(pName[nLen-1]!='/')
1097 {
1098 ulCurrentFileNumber++;
1099 if(PICE_strlen(szCurrentPath))
1100 {
1101 PICE_strcat(szCurrentPath,pName);
1102 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",szCurrentPath));
1103 }
1104 else
1105 {
1106 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",pName));
1107 }
1108 }
1109 else
1110 PICE_strcpy(szCurrentPath,pName);
1111 }
1112 else
1113 {
1114 szCurrentPath[0]=0;
1115 }
1116 break;
1117 case N_GSYM:
1118 //ei File number count is not reliable
1119 if( 1 /*ulCurrentFileNumber == ulFileNumber*/)
1120 {
1121 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): %s\n",pName));
1122
1123 // handle multi-line symbols
1124 if(PICE_strchr(pName,'\\'))
1125 {
1126 if(PICE_strlen(szAccumulatedName))
1127 {
1128 PICE_strcat(szAccumulatedName,pName);
1129 }
1130 else
1131 {
1132 PICE_strcpy(szAccumulatedName,pName);
1133 }
1134 szAccumulatedName[PICE_strlen(szAccumulatedName)-1]=0;
1135 //DPRINT((0,"accum. %s\n",szAccumulatedName));
1136 }
1137 else
1138 {
1139 if(PICE_strlen(szAccumulatedName)==0)
1140 {
1141 PICE_strcpy(szAccumulatedName,pName);
1142 }
1143 else
1144 {
1145 PICE_strcat(szAccumulatedName,pName);
1146 }
1147 pNameTemp = szAccumulatedName;
1148
1149 // symbol-name:type-identifier type-number =
1150 nLen = StrLenUpToWhiteChar(pNameTemp,":");
1151 if((pTypeDefIncluded = PICE_strchr(pNameTemp,'=')) && pNameTemp[nLen+1]=='G')
1152 {
1153 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): symbol includes type definition (%s)\n",pNameTemp));
1154 pTypeNumber = pNameTemp+nLen+1;
1155 if((ulCurrentTypeNumber = ExtractTypeNumber(pTypeNumber)) )
1156 {
1157 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): type-number %x\n",ulCurrentTypeNumber));
1158 if(ulCurrentTypeNumber == ulTypeNumber)
1159 {
1160 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): typenumber %x matches!\n",ulCurrentTypeNumber));
1161 return pNameTemp;
1162 }
1163 }
1164 }
1165 *szAccumulatedName = 0;
1166 }
1167 }
1168 break;
1169 }
1170 pStab++;
1171 }
1172 return NULL;
1173 }
1174
1175 //*************************************************************************
1176 // FindTypeDefinition()
1177 //
1178 //*************************************************************************
1179 LPSTR FindTypeDefinition(PICE_SYMBOLFILE_HEADER* pSymbols,ULONG ulTypeNumber,ULONG ulFileNumber)
1180 {
1181 ULONG i;
1182 PSTAB_ENTRY pStab;
1183 LPSTR pStr,pName,pTypeString;
1184 int nStabLen;
1185 int nOffset=0,nNextOffset=0,strLen;
1186 static char szAccumulatedName[2048];
1187 ULONG ulCurrentTypeNumber,ulCurrentFileNumber=0;
1188 LPSTR pTypeSymbol;
1189 static char szCurrentPath[256];
1190
1191 ENTER_FUNC();
1192 DPRINT((0,"FindTypeDefinition(%u,%u)\n",ulTypeNumber,ulFileNumber));
1193
1194 *szAccumulatedName = 0;
1195
1196 pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
1197 nStabLen = pSymbols->ulSizeOfStabs;
1198 pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
1199
1200 for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
1201 {
1202 pName = &pStr[pStab->n_strx + nOffset];
1203
1204 switch(pStab->n_type)
1205 {
1206 case N_UNDF:
1207 nOffset += nNextOffset;
1208 nNextOffset = pStab->n_value;
1209 break;
1210 case N_SO:
1211 if((strLen = PICE_strlen(pName)))
1212 {
1213 if(pName[strLen-1]!='/')
1214 {
1215 ulCurrentFileNumber++;
1216 if(PICE_strlen(szCurrentPath))
1217 {
1218 PICE_strcat(szCurrentPath,pName);
1219 DPRINT((0,"FindTypeDefinition()1: cha %s, %u\n",szCurrentPath, ulCurrentFileNumber));
1220 }
1221 else
1222 {
1223 DPRINT((0,"FindTypeDefinition(): cha %s, %u\n",pName, ulCurrentFileNumber));
1224 }
1225 }
1226 else
1227 PICE_strcpy(szCurrentPath,pName);
1228 }
1229 else
1230 {
1231 szCurrentPath[0]=0;
1232 }
1233 break;
1234 case N_LSYM:
1235 // stab has no value -> must be type definition
1236 //ei File number count is not reliable
1237 if(pStab->n_value == 0 /*&& ulCurrentFileNumber==ulFileNumber*/)
1238 {
1239 DPRINT((0,"FindTypeDefinition(): pre type definition %s\n",pName));
1240 // handle multi-line symbols
1241 if(strrchr(pName,'\\'))
1242 {
1243 if(PICE_strlen(szAccumulatedName))
1244 {
1245 PICE_strcat(szAccumulatedName,pName);
1246 DPRINT((0,"FindTypeDefinition(): [1] accum. %s\n",szAccumulatedName));
1247 }
1248 else
1249 {
1250 PICE_strcpy(szAccumulatedName,pName);
1251 DPRINT((0,"FindTypeDefinition(): [2] accum. %s\n",szAccumulatedName));
1252 }
1253 szAccumulatedName[PICE_strlen(szAccumulatedName)-1]=0;
1254 }
1255 else
1256 {
1257 DPRINT((0,"FindTypeDefinition(): [3] accum. %s, pname: %s\n",szAccumulatedName, pName));
1258 if(PICE_strlen(szAccumulatedName)==0)
1259 {
1260 PICE_strcpy(szAccumulatedName,pName);
1261 }
1262 else
1263 {
1264 PICE_strcat(szAccumulatedName,pName);
1265 }
1266 pTypeString = szAccumulatedName;
1267
1268 pTypeSymbol = PICE_strchr(pTypeString,':');
1269 if(pTypeSymbol && (*(pTypeSymbol+1)=='t' || *(pTypeSymbol+1)=='T'))
1270 {
1271 // parse it
1272 ulCurrentTypeNumber = ExtractTypeNumber(pTypeString);
1273 DPRINT((0,"FindTypeDefinition(): ulCurrType: %u, LSYM is type %s\n",ulCurrentTypeNumber,pName));
1274 if(ulCurrentTypeNumber == ulTypeNumber)
1275 {
1276 DPRINT((0,"FindTypeDefinition(): type definition %s\n",pTypeString));
1277 return pTypeString;
1278 }
1279 }
1280 *szAccumulatedName=0;
1281 }
1282 }
1283 break;
1284 }
1285 pStab++;
1286 }
1287
1288 return FindTypeDefinitionForCombinedTypes(pSymbols,ulTypeNumber,ulFileNumber);
1289
1290 }
1291
1292 //*************************************************************************
1293 // TruncateString()
1294 //
1295 //*************************************************************************
1296 LPSTR TruncateString(LPSTR p,char c)
1297 {
1298 static char temp[1024];
1299 LPSTR pTemp;
1300
1301 pTemp = temp;
1302
1303 while(*p!=0 && *p!=c)
1304 *pTemp++ = *p++;
1305
1306 *pTemp = 0;
1307
1308 return temp;
1309 }
1310
1311 //*************************************************************************
1312 // FindLocalsByAddress()
1313 //
1314 // find all locals for a given address by first looking up the function
1315 // and then it's locals
1316 //*************************************************************************
1317 PLOCAL_VARIABLE FindLocalsByAddress(ULONG addr)
1318 {
1319 ULONG i;
1320 PSTAB_ENTRY pStab;
1321 LPSTR pStr,pName;
1322 int nStabLen;
1323 int nOffset=0,nNextOffset=0;
1324 PICE_SYMBOLFILE_HEADER* pSymbols;
1325 static char szCurrentFunction[256];
1326 static char szCurrentPath[256];
1327 LPSTR pFunctionName;
1328 ULONG start,end,strLen;
1329 ULONG ulTypeNumber,ulCurrentFileNumber=0;
1330 LPSTR pTypedef;
1331 ULONG ulNumLocalVars=0;
1332
1333 DPRINT((0,"FindLocalsByAddress()\n"));
1334
1335 pFunctionName = FindFunctionByAddress(addr,&start,&end);
1336 DPRINT((0,"FindLocalsByAddress(): pFunctionName = %s\n",pFunctionName));
1337 if(pFunctionName)
1338 {
1339 pSymbols = FindModuleSymbols(addr);
1340 if(pSymbols)
1341 {
1342 pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
1343 nStabLen = pSymbols->ulSizeOfStabs;
1344 pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
1345
1346 for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
1347 {
1348 pName = &pStr[pStab->n_strx + nOffset];
1349
1350 DPRINT((0,"FindLocalsByAddress(): %x %x %x %x %x\n",
1351 pStab->n_strx,
1352 pStab->n_type,
1353 pStab->n_other,
1354 pStab->n_desc,
1355 pStab->n_value));
1356
1357 switch(pStab->n_type)
1358 {
1359 case N_UNDF:
1360 nOffset += nNextOffset;
1361 nNextOffset = pStab->n_value;
1362 break;
1363 case N_SO:
1364 if((strLen = PICE_strlen(pName)))
1365 {
1366 if(pName[strLen-1]!='/')
1367 {
1368 ulCurrentFileNumber++;
1369 if(PICE_strlen(szCurrentPath))
1370 {
1371 PICE_strcat(szCurrentPath,pName);
1372 DPRINT((0,"changing source file1 %s, %u\n",szCurrentPath,ulCurrentFileNumber));
1373 }
1374 else
1375 {
1376 DPRINT((0,"changing source file %s, %u\n",pName,ulCurrentFileNumber));
1377 }
1378 }
1379 else
1380 PICE_strcpy(szCurrentPath,pName);
1381 }
1382 else
1383 {
1384 szCurrentPath[0]=0;
1385 }
1386 break;
1387 case N_LSYM:
1388 // if we're in the function we're looking for
1389 if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
1390 {
1391 DPRINT((0,"local variable1 %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
1392 ulTypeNumber = ExtractTypeNumber(pName);
1393 DPRINT((0,"type number = %u\n",ulTypeNumber));
1394 if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
1395 {
1396 DPRINT((0,"pTypedef: %x\n", pTypedef));
1397 PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
1398 PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
1399 local_vars[ulNumLocalVars].value = (CurrentEBP+pStab->n_value);
1400 local_vars[ulNumLocalVars].offset = pStab->n_value;
1401 local_vars[ulNumLocalVars].line = pStab->n_desc;
1402 local_vars[ulNumLocalVars].bRegister = FALSE;
1403 ulNumLocalVars++;
1404 }
1405 }
1406 break;
1407 case N_PSYM:
1408 // if we're in the function we're looking for
1409 if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
1410 {
1411 DPRINT((0,"parameter variable %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
1412 ulTypeNumber = ExtractTypeNumber(pName);
1413 DPRINT((0,"type number = %x\n",ulTypeNumber));
1414 if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
1415 {
1416 PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
1417 PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
1418 local_vars[ulNumLocalVars].value = (CurrentEBP+pStab->n_value);
1419 local_vars[ulNumLocalVars].offset = pStab->n_value;
1420 ulNumLocalVars++;
1421 }
1422 }
1423 break;
1424 case N_RSYM:
1425 // if we're in the function we're looking for
1426 if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
1427 {
1428 DPRINT((0,"local variable2 %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
1429 ulTypeNumber = ExtractTypeNumber(pName);
1430 DPRINT((0,"type number = %x\n",ulTypeNumber));
1431 if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
1432 {
1433 PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
1434 PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
1435 local_vars[ulNumLocalVars].value = (LocalRegs[pStab->n_value]);
1436 local_vars[ulNumLocalVars].offset = pStab->n_value;
1437 local_vars[ulNumLocalVars].line = pStab->n_desc;
1438 local_vars[ulNumLocalVars].bRegister = TRUE;
1439 ulNumLocalVars++;
1440 }
1441 }
1442 break;
1443 case N_FUN:
1444 if(PICE_strlen(pName))
1445 {
1446 ULONG len;
1447
1448 len=StrLenUpToWhiteChar(pName,":");
1449 PICE_strncpy(szCurrentFunction,pName,len);
1450 szCurrentFunction[len]=0;
1451 DPRINT((0,"function %s\n",szCurrentFunction));
1452 }
1453 else
1454 {
1455 DPRINT((0,"END of function %s\n",szCurrentFunction));
1456 szCurrentFunction[0]=0;
1457 if(ulNumLocalVars)
1458 {
1459 *local_vars[ulNumLocalVars].name = 0;
1460 return local_vars;
1461 }
1462 }
1463 break;
1464 }
1465 pStab++;
1466 }
1467 }
1468 }
1469 return NULL;
1470 }
1471
1472 //*************************************************************************
1473 // FindSourceLineForAddress()
1474 //
1475 //*************************************************************************
1476 LPSTR FindSourceLineForAddress(ULONG addr,PULONG pulLineNumber,LPSTR* ppSrcStart,LPSTR* ppSrcEnd,LPSTR* ppFilename)
1477 {
1478 ULONG i; // index for walking through STABS
1479 PSTAB_ENTRY pStab; // pointer to STABS
1480 LPSTR pStr,pName; // pointer to STAB strings and current STAB string
1481 int nStabLen; // length of STAB section in bytes
1482 int nOffset=0,nNextOffset=0; // offset and next offset in string table
1483 PICE_SYMBOLFILE_HEADER* pSymbols; // pointer to module's STAB symbol table
1484 static char szCurrentFunction[256];
1485 static char szCurrentPath[256];
1486 static char szWantedPath[256];
1487 LPSTR pFunctionName; // name of function that brackets the current address
1488 ULONG start,end,strLen,ulMinValue=0xFFFFFFFF;
1489 LPSTR pSrcLine=NULL;
1490 BOOLEAN bFirstOccurence = TRUE;
1491
1492 // lookup the functions name and start-end (external symbols)
1493 pFunctionName = FindFunctionByAddress(addr,&start,&end);
1494 DPRINT((0,"FindSourceLineForAddress: for function: %s\n", pFunctionName));
1495
1496 if(pFunctionName)
1497 {
1498 // lookup the modules symbol table (STABS)
1499 pSymbols = FindModuleSymbols(addr);
1500 DPRINT((0,"FindSourceLineForAddress: pSymbols %x\n", pSymbols));
1501 if(pSymbols)
1502 {
1503 DPRINT((0,"FindSourceLineForAddress: pSymbols->ulNumberOfSrcFiles %x\n", pSymbols->ulNumberOfSrcFiles));
1504 // no source files so we don't need to lookup anything
1505 if(!pSymbols->ulNumberOfSrcFiles)
1506 return NULL;
1507
1508 // prepare STABS access
1509 pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
1510 nStabLen = pSymbols->ulSizeOfStabs;
1511 pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
1512
1513 // walk over all STABS
1514 for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
1515 {
1516 // the name string corresponding to the STAB
1517 pName = &pStr[pStab->n_strx + nOffset];
1518
1519 // switch STAB type
1520 switch(pStab->n_type)
1521 {
1522 // change offset of name strings
1523 case N_UNDF:
1524 nOffset += nNextOffset;
1525 nNextOffset = pStab->n_value;
1526 break;
1527 // source file change
1528 case N_SO:
1529 DPRINT((0,"changing source file %s\n",pName));
1530 // if filename has a length record it
1531 if((strLen = PICE_strlen(pName)))
1532 {
1533 PICE_strcpy(szCurrentPath,pName);
1534 }
1535 // else empty filename
1536 else
1537 {
1538 szCurrentPath[0]=0;
1539 }
1540 break;
1541 // sub-source file change
1542 case N_SOL:
1543 DPRINT((0,"changing sub source file %s\n",pName));
1544 // if filename has a length record it
1545 if((strLen = PICE_strlen(pName)))
1546 {
1547 PICE_strcpy(szCurrentPath,pName);
1548 }
1549 // else empty filename
1550 else
1551 {
1552 szCurrentPath[0]=0;
1553 }
1554 break;
1555 // a function symbol
1556 case N_FUN:
1557 if(!PICE_strlen(pName))
1558 {// it's the end of a function
1559 DPRINT((0,"END of function %s\n",szCurrentFunction));
1560
1561 szCurrentFunction[0]=0;
1562
1563 // in case we haven't had a zero delta match we return from here
1564 if(pSrcLine)
1565 return pSrcLine;
1566
1567 break;
1568 }
1569 else
1570 {// if it has a length it's the start of a function
1571 ULONG len;
1572 // extract the name only, the type string is of no use here
1573 len=StrLenUpToWhiteChar(pName,":");
1574 PICE_strncpy(szCurrentFunction,pName,len);
1575 szCurrentFunction[len]=0;
1576
1577 DPRINT((0,"function %s\n",szCurrentFunction));
1578 }
1579 //intentional fall through
1580
1581 // line number
1582 case N_SLINE:
1583 // if we're in the function we're looking for
1584 if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
1585 {
1586 DPRINT((0,"cslnum#%u for addr.%x (fn @ %x) ulMinVal=%x ulDelta=%x\n",pStab->n_desc,start+pStab->n_value,start,ulMinValue,(addr-(start+pStab->n_value))));
1587
1588 if(bFirstOccurence)
1589 {
1590 PICE_strcpy(szWantedPath,szCurrentPath);
1591 DPRINT((0,"source file must be %s\n",szWantedPath));
1592 bFirstOccurence = FALSE;
1593 }
1594 DPRINT((0,"wanted %s, current: %s\n",szWantedPath, szCurrentPath));
1595 // we might have a match if our address is greater than the one in the STAB
1596 // and we're lower or equal than minimum value
1597 if(addr>=start+pStab->n_value &&
1598 (addr-(start+pStab->n_value))<=ulMinValue &&
1599 PICE_strcmpi(szWantedPath,szCurrentPath)==0 )
1600 {
1601 ULONG j;
1602 PICE_SYMBOLFILE_SOURCE* pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pSymbols+pSymbols->ulOffsetToSrcFiles);
1603
1604 DPRINT((0,"code source line number #%u for addr. %x found!\n",pStab->n_desc,start+pStab->n_value));
1605
1606 // compute new minimum
1607 ulMinValue = addr-(start+pStab->n_value);
1608
1609 // if we have a pointer for storage of line number, store it
1610 if(pulLineNumber)
1611 *pulLineNumber = pStab->n_desc;
1612
1613 // NB: should put this somewhere else so that it's not done all the time
1614 // if we have source files at all
1615 DPRINT((0,"%u source files @ %x\n",pSymbols->ulNumberOfSrcFiles,pSrc));
1616
1617 // for all source files in this module
1618 for(j=0;j<pSymbols->ulNumberOfSrcFiles;j++)
1619 {
1620 LPSTR pSlash;
1621 ULONG currlen, fnamelen;
1622
1623 currlen = PICE_strlen( szCurrentPath );
1624 fnamelen = PICE_strlen( pSrc->filename );
1625 pSlash = pSrc->filename + fnamelen - currlen;
1626
1627 //DPRINT((0,"pSlash: %s, szCurrentPath: %s\n", pSlash, szCurrentPath));
1628 // if base name matches current path we have found the correct source file
1629 if(PICE_strcmpi(pSlash,szCurrentPath)==0)
1630 {
1631 // the linenumber
1632 ULONG k = pStab->n_desc;
1633
1634 DPRINT((0,"found src file %s @ %x\n",pSrc->filename,pSrc));
1635
1636 // store the pointer to the filename
1637 if(ppFilename)
1638 *ppFilename = pSrc->filename;
1639
1640 if(pSrc->ulOffsetToNext > sizeof(PICE_SYMBOLFILE_SOURCE))
1641 {
1642 // get a pointer to the source file (right after the file header)
1643 pSrcLine = (LPSTR)((ULONG)pSrc+sizeof(PICE_SYMBOLFILE_SOURCE));
1644
1645 // store the source start and end address
1646 if(ppSrcStart)
1647 *ppSrcStart = pSrcLine;
1648 if(ppSrcEnd)
1649 *ppSrcEnd = pSrcLine+pSrc->ulOffsetToNext-sizeof(PICE_SYMBOLFILE_SOURCE);
1650
1651 // goto to the right line
1652 while(--k)
1653 {
1654 while(*pSrcLine!=0 && *pSrcLine!=0x0a && *pSrcLine!=0x0d)
1655 pSrcLine++;
1656 if(!IsAddressValid((ULONG)pSrcLine))
1657 return NULL;
1658 pSrcLine++;
1659 }
1660
1661 if(ulMinValue == 0)
1662 return pSrcLine;
1663 }
1664 else
1665 {
1666 DPRINT((0,"src file descriptor found, but contains no source\n"));
1667 }
1668
1669 break;
1670 }
1671 (ULONG)pSrc += pSrc->ulOffsetToNext;
1672 }
1673 }
1674 }
1675 break;
1676 }
1677 pStab++;
1678 }
1679 }
1680 }
1681 DPRINT((0,"FindSourceLineForAddress: exit 1\n"));
1682 return NULL;
1683 }
1684
1685 //*************************************************************************
1686 // FindAddressForSourceLine()
1687 //
1688 //*************************************************************************
1689 BOOLEAN FindAddressForSourceLine(ULONG ulLineNumber,LPSTR pFilename,PDEBUG_MODULE pMod,PULONG pValue)
1690 {
1691 ULONG i;
1692 PSTAB_ENTRY pStab;
1693 LPSTR pStr,pName;
1694 int nStabLen;
1695 int nOffset=0,nNextOffset=0;
1696 PICE_SYMBOLFILE_HEADER* pSymbols;
1697 static char szCurrentFunction[256];
1698 static char szCurrentPath[256];
1699 ULONG strLen,addr,ulMinValue=0xFFFFFFFF;
1700 BOOLEAN bFound = FALSE;
1701
1702 DPRINT((0,"FindAddressForSourceLine(%u,%s,%x)\n",ulLineNumber,pFilename,(ULONG)pMod));
1703
1704 addr = (ULONG)pMod->BaseAddress;
1705
1706 pSymbols = FindModuleSymbols(addr);
1707 if(pSymbols)
1708 {
1709 pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
1710 nStabLen = pSymbols->ulSizeOfStabs;
1711 pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
1712
1713 for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
1714 {
1715 pName = &pStr[pStab->n_strx + nOffset];
1716
1717 switch(pStab->n_type)
1718 {
1719 case N_UNDF:
1720 nOffset += nNextOffset;
1721 nNextOffset = pStab->n_value;
1722 break;
1723 case N_SO:
1724 if((strLen = PICE_strlen(pName)))
1725 {
1726 if(pName[strLen-1]!='/')
1727 {
1728 if(PICE_strlen(szCurrentPath))
1729 {
1730 PICE_strcat(szCurrentPath,pName);
1731 DPRINT((0,"changing source file %s\n",szCurrentPath));
1732 }
1733 else
1734 {
1735 DPRINT((0,"changing source file %s\n",pName));
1736 PICE_strcpy(szCurrentPath,pName);
1737 }
1738 }
1739 else
1740 PICE_strcpy(szCurrentPath,pName);
1741 }
1742 else
1743 {
1744 szCurrentPath[0]=0;
1745 }
1746 break;
1747 case N_SLINE:
1748 // if we're in the function we're looking for
1749 if(PICE_strcmpi(pFilename,szCurrentPath)==0)
1750 {
1751 if(pStab->n_desc>=ulLineNumber && (pStab->n_desc-ulLineNumber)<=ulMinValue)
1752 {
1753 ulMinValue = pStab->n_desc-ulLineNumber;
1754
1755 DPRINT((0,"code source line number #%u for offset %x in function @ %s)\n",pStab->n_desc,pStab->n_value,szCurrentFunction));
1756 addr = FindFunctionInModuleByName(szCurrentFunction,pMod);
1757 if(addr)
1758 {
1759 *pValue = addr + pStab->n_value;
1760 bFound = TRUE;
1761 }
1762 }
1763 }
1764 break;
1765 case N_FUN:
1766 if(PICE_strlen(pName))
1767 {
1768 ULONG len;
1769
1770 len=StrLenUpToWhiteChar(pName,":");
1771 PICE_strncpy(szCurrentFunction,pName,len);
1772 szCurrentFunction[len]=0;
1773 DPRINT((0,"function %s\n",szCurrentFunction));
1774 }
1775 else
1776 {
1777 DPRINT((0,"END of function %s\n",szCurrentFunction));
1778 szCurrentFunction[0]=0;
1779 }
1780 break;
1781 }
1782 pStab++;
1783 }
1784 }
1785 return bFound;
1786 }
1787
1788 //*************************************************************************
1789 // ListSymbolStartingAt()
1790 // iterate through the list of module symbols (both functions and variables)
1791 //*************************************************************************
1792 ULONG ListSymbolStartingAt(PDEBUG_MODULE pMod,PICE_SYMBOLFILE_HEADER* pSymbols,ULONG index,LPSTR pOutput)
1793 {
1794 PIMAGE_SYMBOL pSym, pSymEnd;
1795 LPSTR pStr;
1796 PIMAGE_SECTION_HEADER pShdr;
1797
1798 DPRINT((0,"ListSymbolStartingAt(%x,%u)\n",(ULONG)pSymbols,index));
1799 DPRINT((0,"ListSymbolStartingAt(): ulOffsetToGlobals = %x ulSizeofGlobals = %x\n",pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals));
1800 pSym = (PIMAGE_SYMBOL)((ULONG)pSymbols+pSymbols->ulOffsetToGlobals);
1801 pSymEnd = (PIMAGE_SYMBOL)((ULONG)pSym+pSymbols->ulSizeOfGlobals);
1802 pStr = (LPSTR)((ULONG)pSymbols+pSymbols->ulOffsetToGlobalsStrings);
1803 pShdr = (PIMAGE_SECTION_HEADER)((ULONG)pSymbols+pSymbols->ulOffsetToHeaders);
1804
1805 pSym += index;
1806
1807 while( pSym < pSymEnd )
1808 {
1809 LPSTR pName;
1810
1811 if(((pSym->Type == 0x0) || (pSym->Type == 0x20) ) &&
1812 ((pSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) /*|| (pSym->StorageClass==IMAGE_SYM_CLASS_STATIC)*/) &&
1813 (pSym->SectionNumber > 0 ))
1814 {
1815 PIMAGE_SECTION_HEADER pShdrThis = (PIMAGE_SECTION_HEADER)pShdr + (pSym->SectionNumber-1);
1816 ULONG section_flags;
1817 ULONG start;
1818
1819 DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x\n",pSym->SectionNumber,(ULONG)pShdrThis));
1820
1821 if(!IsRangeValid((ULONG)pShdrThis,sizeof(IMAGE_SECTION_HEADER)) )
1822 {
1823 DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x is not a valid pointer\n",pSym->SectionNumber,(ULONG)pShdrThis));
1824 return FALSE;
1825 }
1826 section_flags = pShdrThis->Characteristics;
1827 //to get address in the memory we base address of the module and
1828 //add offset of the section and then add offset of the symbol from
1829 //the begining of the section
1830
1831 start = ((ULONG)pMod->BaseAddress+pShdrThis->VirtualAddress+pSym->Value);
1832 if(pSym->N.Name.Short){
1833 //name is in the header. it's not zero terminated. have to copy.
1834 PICE_sprintf(pOutput,"%.8X (%s) %.8s\n",start,(section_flags&IMAGE_SCN_CNT_CODE)?"TEXT":"DATA",pSym->N.ShortName);
1835 }
1836 else{
1837 ASSERT(pSym->N.Name.Long<=pSymbols->ulSizeOfGlobalsStrings); //sanity check
1838 pName = pStr+pSym->N.Name.Long;
1839 if(!IsAddressValid((ULONG)pName))
1840 {
1841 DPRINT((0,"ListSymbolStartingAt(): pName = %x is not a valid pointer\n",pName));
1842 return 0;
1843 }
1844 PICE_sprintf(pOutput,"%.8X (%s) %s\n",start,(section_flags&IMAGE_SCN_CNT_CODE)?"TEXT":"DATA",pName);
1845 }
1846
1847 if((pSym+pSym->NumberOfAuxSymbols+1)<(pSymEnd))
1848 return (index+pSym->NumberOfAuxSymbols+1);
1849 }
1850 index += pSym->NumberOfAuxSymbols + 1;
1851 pSym += pSym->NumberOfAuxSymbols + 1;
1852 }
1853 return 0;
1854 }
1855
1856 //*************************************************************************
1857 // SanityCheckExports()
1858 //
1859 //*************************************************************************
1860 BOOLEAN SanityCheckExports(void)
1861 {
1862 BOOLEAN bResult = FALSE;
1863 ULONG i,ulValue,incr;
1864
1865 Print(OUTPUT_WINDOW,"pICE: sanity-checking exports...\n");
1866 return TRUE;
1867 /* fix later!!! do we really need to cross reference two kinds of symbolic info?
1868 if(fake_kernel_module.nsyms && fake_kernel_module.syms)
1869 {
1870 incr = (fake_kernel_module.nsyms/4);
1871 if(!incr)incr = 1;
1872 for(i=0;i<fake_kernel_module.nsyms;i+=incr)
1873 {
1874 if(ScanExports((char*)fake_kernel_module.syms[i].name,&ulValue) )
1875 {
1876 if(!(i%25))
1877 {
1878 ClrLine(wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
1879 PICE_sprintf(tempSym,"pICE: sanity-checking exports %u/%u",
1880 i,
1881 fake_kernel_module.nsyms);
1882 PutChar(tempSym,1,wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
1883 }
1884
1885 if(fake_kernel_module.syms[i].value != ulValue)
1886 {
1887 PICE_sprintf(tempSym,"pICE: %s doesn't match (%.8X != %.8X)\n",
1888 fake_kernel_module.syms[i].name,
1889 fake_kernel_module.syms[i].value,
1890 ulValue);
1891 Print(OUTPUT_WINDOW,tempSym);
1892
1893 return FALSE;
1894 }
1895 }
1896 }
1897
1898 bResult = TRUE;
1899 }
1900
1901 return bResult;
1902 */
1903 }
1904
1905 //*************************************************************************
1906 // LoadExports()
1907 //
1908 //*************************************************************************
1909 BOOLEAN LoadExports(void)
1910 {
1911 HANDLE hf;
1912 BOOLEAN bResult = TRUE;
1913
1914 ENTER_FUNC();
1915
1916 Print(OUTPUT_WINDOW,"pICE: loading exports...\n");
1917 hf = PICE_open(L"\\SystemRoot\\symbols\\ntoskrnl.map",OF_READ);
1918 /*
1919 if(hf)
1920 {
1921 Print(OUTPUT_WINDOW,"pICE: no System.map in /boot\n");
1922 hf = PICE_open("/System.map",OF_READ);
1923 }
1924 */
1925
1926 if(hf)
1927 {
1928 //mm_segment_t oldfs;
1929 size_t len;
1930
1931 len = PICE_len(hf);
1932 if(len)
1933 {
1934 DPRINT((0,"file len = %d\n",len));
1935
1936 pExports = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
1937
1938 DPRINT((0,"pExports = %x\n",pExports));
1939
1940 if(pExports)
1941 {
1942 //oldfs = get_fs(); set_fs(KERNEL_DS);
1943 ulExportLen = len;
1944 ((PUCHAR)pExports)[len]=0;
1945 if(len == PICE_read(hf,pExports,len))
1946 {
1947 DPRINT((0,"success reading system map!\n"));
1948 PICE_sprintf(tempSym,"pICE: ntoskrnl.sym @ %x (size %x)\n",pExports,len);
1949 Print(OUTPUT_WINDOW,tempSym);
1950 }
1951 else
1952 DbgPrint("error reading ntoskrnl map!\n");
1953 //set_fs(oldfs);
1954 }
1955 }
1956 PICE_close(hf);
1957 }
1958 else
1959 {
1960 Print(OUTPUT_WINDOW,"pICE: no ntoskrnl.sys \n");
1961 Print(OUTPUT_WINDOW,"pICE: could not load exports...\n");
1962 bResult = FALSE;
1963 }
1964
1965 LEAVE_FUNC();
1966
1967 return bResult;
1968 }
1969
1970 //*************************************************************************
1971 // UnloadExports()
1972 //
1973 //*************************************************************************
1974 void UnloadExports(void)
1975 {
1976 ENTER_FUNC();
1977 if(pExports)
1978 {
1979 DPRINT((0,"freeing %x\n",pExports));
1980 PICE_free(pExports);
1981 pExports = NULL;
1982 }
1983 LEAVE_FUNC();
1984 }
1985
1986 //*************************************************************************
1987 // LoadSymbols()
1988 //
1989 //*************************************************************************
1990 PICE_SYMBOLFILE_HEADER* LoadSymbols(LPSTR filename)
1991 {
1992 HANDLE hf;
1993 PICE_SYMBOLFILE_HEADER* pSymbols=NULL;
1994 WCHAR tempstr[256];
1995 int conv;
1996 ENTER_FUNC();
1997
1998 if( !( conv = PICE_MultiByteToWideChar(CP_ACP, NULL, filename, -1, tempstr, 256 ) ) )
1999 {
2000 DPRINT((0,"Can't convert module name.\n"));
2001 return NULL;
2002 }
2003 DPRINT((0,"LoadSymbols: filename %s, tempstr %S, conv: %d\n", filename, tempstr, conv));
2004
2005 if(ulNumSymbolsLoaded<DIM(apSymbols))
2006 {
2007 hf = PICE_open(tempstr,OF_READ);
2008 DPRINT((0,"LoadSymbols: hf: %x, file: %S\n",hf, tempstr));
2009 if(hf)
2010 {
2011 //mm_segment_t oldfs;
2012 size_t len;
2013
2014 DPRINT((0,"hf = %x\n",hf));
2015
2016 len = PICE_len(hf);
2017 DPRINT((0,"file len = %d\n",len));
2018
2019 if(len)
2020 {
2021 pSymbols = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
2022 DPRINT((0,"pSymbols = %x\n",pSymbols));
2023
2024 if(pSymbols)
2025 {
2026 //oldfs = get_fs(); set_fs(KERNEL_DS);
2027 if(len == PICE_read(hf,(PVOID)pSymbols,len))
2028 {
2029 DPRINT((0,"LoadSymbols(): success reading symbols!\n"));
2030 DPRINT((0,"LoadSymbols(): pSymbols->magic = %X\n",pSymbols->magic));
2031 }
2032 //set_fs(oldfs);
2033
2034
2035 if(pSymbols->magic == PICE_MAGIC)
2036 {
2037 DPRINT((0,"magic = %X\n",pSymbols->magic));
2038 DPRINT((0,"name = %S\n",pSymbols->name));
2039 DPRINT((0,"ulOffsetToHeaders,ulSizeOfHeader = %X,%X\n",pSymbols->ulOffsetToHeaders,pSymbols->ulSizeOfHeader));
2040 DPRINT((0,"ulOffsetToGlobals,ulSizeOfGlobals = %X,%X\n",pSymbols->ulOffsetToGlobals,pSymbols->ulSizeOfGlobals));
2041 DPRINT((0,"ulOffsetToGlobalsStrings,ulSizeOfGlobalsStrings = %X,%X\n",pSymbols->ulOffsetToGlobalsStrings,pSymbols->ulSizeOfGlobalsStrings));
2042 DPRINT((0,"ulOffsetToStabs,ulSizeOfStabs = %X,%X\n",pSymbols->ulOffsetToStabs,pSymbols->ulSizeOfStabs));
2043 DPRINT((0,"ulOffsetToStabsStrings,ulSizeOfStabsStrings = %X,%X\n",pSymbols->ulOffsetToStabsStrings,pSymbols->ulSizeOfStabsStrings));
2044 DPRINT((0,"ulOffsetToSrcFiles,ulNumberOfSrcFiles = %X,%X\n",pSymbols->ulOffsetToSrcFiles,pSymbols->ulNumberOfSrcFiles));
2045 DPRINT((0,"pICE: symbols loaded for module \"%S\" @ %x\n",pSymbols->name,pSymbols));
2046 apSymbols[ulNumSymbolsLoaded++]=pSymbols;
2047 }
2048 else
2049 {
2050 DPRINT((0,"LoadSymbols(): freeing %x\n",pSymbols));
2051 DPRINT((0,"pICE: symbols file \"%s\" corrupt\n",filename));
2052 PICE_free(pSymbols);
2053 }
2054 }
2055
2056 }
2057 PICE_close(hf);
2058 }
2059 else
2060 {
2061 DPRINT((0,"pICE: could not load symbols for %s...\n",filename));
2062 }
2063 }
2064
2065 LEAVE_FUNC();
2066
2067 return pSymbols;
2068 }
2069
2070 //*************************************************************************
2071 // ReloadSymbols()
2072 //
2073 //*************************************************************************
2074 BOOLEAN ReloadSymbols(void)
2075 {
2076 BOOLEAN bResult;
2077
2078 ENTER_FUNC();
2079
2080 UnloadSymbols();
2081
2082 bResult = LoadSymbolsFromConfig(TRUE);
2083
2084 LEAVE_FUNC();
2085
2086 return bResult;
2087 }
2088
2089 //*************************************************************************
2090 // UnloadSymbols()
2091 //
2092 //*************************************************************************
2093 void UnloadSymbols()
2094 {
2095 ULONG i;
2096
2097 ENTER_FUNC();
2098
2099 if(ulNumSymbolsLoaded)
2100 {
2101 for(i=0;i<ulNumSymbolsLoaded;i++)
2102 {
2103 DPRINT((0,"freeing [%u] %x\n",i,apSymbols[i]));
2104 PICE_free(apSymbols[i]);
2105 apSymbols[i] = NULL;
2106 }
2107 ulNumSymbolsLoaded = 0;
2108 }
2109 LEAVE_FUNC();
2110 }
2111
2112 //*************************************************************************
2113 // LoadSymbolsFromConfig()
2114 //
2115 //*************************************************************************
2116 BOOLEAN LoadSymbolsFromConfig(BOOLEAN bIgnoreBootParams)
2117 {
2118 HANDLE hf;
2119 LPSTR pConfig,pConfigEnd,pTemp;
2120 char temp[256];
2121 ULONG line = 1;
2122 BOOLEAN bResult = FALSE;
2123
2124 ENTER_FUNC();
2125
2126 hf = PICE_open(L"\\SystemRoot\\symbols\\pice.cfg",OF_READ);
2127 if(hf)
2128 {
2129 //mm_segment_t oldfs;
2130 size_t len;
2131
2132 DPRINT((0,"hf = %x\n",hf));
2133
2134 len = PICE_len(hf);
2135 DPRINT((0,"file len = %d\n",len));
2136
2137 if(len)
2138 {
2139 pConfig = PICE_malloc(len+1,NONPAGEDPOOL); // maybe make pool setting an option
2140 DPRINT((0,"pConfig = %x\n",pConfig));
2141 //oldfs = get_fs(); set_fs(KERNEL_DS);
2142
2143 if(len == PICE_read(hf,(PVOID)pConfig,len))
2144 {
2145 //set_fs(oldfs);
2146
2147 pConfigEnd = pConfig + len;
2148
2149 while(pConfig<pConfigEnd)
2150 {
2151 // skip leading spaces
2152 while(*pConfig==' ' && pConfig<pConfigEnd)
2153 pConfig++;
2154 // get ptr to temporary
2155 pTemp = temp;
2156 // fill in temporary with symbol path
2157 while(*pConfig!=0 && *pConfig!=0x0a && *pConfig!=0x0d && pConfig<pConfigEnd)
2158 *pTemp++ = *pConfig++;
2159 // finish up symbol path string
2160 *pTemp = 0;
2161 // skip any line ends
2162 while((*pConfig==0x0a || *pConfig==0x0d) && pConfig<pConfigEnd)
2163 pConfig++;
2164
2165 // finally try to load the symbols
2166 if(PICE_strlen(temp))
2167 {
2168 PICE_SYMBOLFILE_HEADER *pSymbols;
2169
2170 // boot parameter
2171 if(*temp == '!')
2172 {
2173 if(!bIgnoreBootParams)
2174 {
2175 if(!PICE_strlen(szBootParams))
2176 {
2177 PICE_strcpy(szBootParams,temp+1);
2178 DPRINT((0,"pICE: boot params = %s\n",szBootParams));
2179 }
2180 else
2181 {
2182 DPRINT((0,"pICE: boot params already exist! ignoring...\n",szBootParams));
2183 }
2184 }
2185 }
2186 // options
2187 else if(*temp == '+')
2188 {
2189 if(PICE_strlen(temp)>1)
2190 {
2191 if(PICE_strcmpi(temp,"+vga")==0)
2192 {
2193 eTerminalMode = TERMINAL_MODE_VGA_TEXT;
2194 DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_VGA_TEXT\n"));
2195 }
2196 else if(PICE_strcmpi(temp,"+hercules")==0)
2197 {
2198 eTerminalMode = TERMINAL_MODE_HERCULES_GRAPHICS;
2199 DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_HERCULES_GRAPHICS\n"));
2200 }
2201 else if(PICE_strcmpi(temp,"+serial")==0)
2202 {
2203 eTerminalMode = TERMINAL_MODE_SERIAL;
2204 DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_SERIAL\n"));
2205 }
2206 }
2207 else
2208 {
2209 DPRINT((0,"pICE: found option, but no value\n"));
2210 }
2211 }
2212 // comment
2213 else if(*temp == '#')
2214 {
2215 DPRINT((0,"comment out\n"));
2216 }
2217 // symbol file name/path
2218 else
2219 {
2220 DPRINT((0,"Load symbols from file %s\n", temp));
2221 pSymbols = LoadSymbols(temp);
2222 DPRINT((0,"Load symbols from file %s, pSymbols: %x\n", temp, pSymbols));
2223 if(pSymbols)
2224 {
2225 PICE_SYMBOLFILE_SOURCE* pSrc;
2226 LPSTR p;
2227
2228 pSrc = (PICE_SYMBOLFILE_SOURCE*)((ULONG)pSymbols + pSymbols->ulOffsetToSrcFiles);
2229 pCurrentSymbols = pSymbols;
2230 p = strrchr(pSrc->filename,'\\');
2231 if(p)
2232 {
2233 PICE_strcpy(szCurrentFile,p+1);
2234 }
2235 else
2236 {
2237 PICE_strcpy(szCurrentFile,pSrc->filename);
2238 }
2239 }
2240 }
2241 }
2242 else
2243 {
2244 DPRINT((0,"invalid line [%u] in config!\n",line));
2245 }
2246 line++;
2247 }
2248 }
2249 else
2250 {
2251 //set_fs(oldfs);
2252 }
2253 }
2254
2255 PICE_close(hf);
2256 bResult = TRUE;
2257 }
2258 else
2259 {
2260 DPRINT((0,"pICE: config file not found! No symbols loaded.\n"));
2261 DPRINT((0,"pICE: Please make sure to create a file \\systemroot\\symbols\\pice.conf\n"));
2262 DPRINT((0,"pICE: if you want to have symbols for any module loaded.\n"));
2263 }
2264
2265 LEAVE_FUNC();
2266
2267 return bResult;
2268 }
2269
2270
2271 //*************************************************************************
2272 // EVALUATION OF EXPRESSIONS
2273 //*************************************************************************
2274
2275 //*************************************************************************
2276 // SkipSpaces()
2277 //
2278 //*************************************************************************
2279 void SkipSpaces(void)
2280 {
2281 while(pExpression[ulIndex]==' ')
2282 ulIndex++;
2283 };
2284
2285 //*************************************************************************
2286 // FindGlobalStabSymbol()
2287 //
2288 //*************************************************************************
2289 BOOLEAN FindGlobalStabSymbol(LPSTR pExpression,PULONG pValue,PULONG pulTypeNumber,PULONG pulFileNumber)
2290 {
2291 ULONG i;
2292 PSTAB_ENTRY pStab;
2293 LPSTR pStr,pName;
2294 int nStabLen;
2295 int nOffset=0,nNextOffset=0,nLen,strLen;
2296 PICE_SYMBOLFILE_HEADER* pSymbols;
2297 ULONG ulTypeNumber;
2298 static char SymbolName[1024];
2299 static char szCurrentPath[256];
2300 ULONG ulCurrentFileNumber=0;
2301 LPSTR pTypeDefIncluded;
2302 ULONG addr;
2303
2304 // must have a current module
2305 if(pCurrentMod)
2306 {
2307 // in case we query for the kernel we need to use the fake kernel module
2308 addr = (ULONG)pCurrentMod->BaseAddress;
2309
2310 // find the symbols for the module
2311 pSymbols = FindModuleSymbols(addr);
2312 if(pSymbols)
2313 {
2314 // prepare table access
2315 pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
2316 nStabLen = pSymbols->ulSizeOfStabs;
2317 pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
2318 // starting at file 0
2319 *pulFileNumber = 0;
2320
2321 // go through stabs
2322 for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
2323 {
2324 pName = &pStr[pStab->n_strx + nOffset];
2325
2326 switch(pStab->n_type)
2327 {
2328 // an N_UNDF symbol marks a change of string table offset
2329 case N_UNDF:
2330 nOffset += nNextOffset;
2331 nNextOffset = pStab->n_value;
2332 break;
2333 // a source file symbol
2334 case N_SO:
2335 if((strLen = PICE_strlen(pName)))
2336 {
2337 if(pName[strLen-1]!='/')
2338 {
2339 ulCurrentFileNumber++;
2340 if(PICE_strlen(szCurrentPath))
2341 {
2342 PICE_strcat(szCurrentPath,pName);
2343 DPRINT((0,"changing source file %s\n",szCurrentPath));
2344 }
2345 else
2346 {
2347 DPRINT((0,"changing source file %s\n",pName));
2348 }
2349 }
2350 else
2351 PICE_strcpy(szCurrentPath,pName);
2352 }
2353 else
2354 {
2355 szCurrentPath[0]=0;
2356 }
2357 break;
2358 case N_GSYM:
2359 case N_LSYM:
2360 case N_PSYM:
2361 // symbol-name:type-identifier type-number =
2362 nLen = StrLenUpToWhiteChar(pName,":");
2363 PICE_strncpy(SymbolName,pName,nLen);
2364 SymbolName[nLen] = 0;
2365 if(PICE_strcmpi(SymbolName,pExpression)==0)
2366 {
2367 DPRINT((0,"global symbol %s\n",pName));
2368 // extract type-number from stab
2369 ulTypeNumber = ExtractTypeNumber(pName);
2370 DPRINT((0,"type number = %x, from %s\n",ulTypeNumber, pName));
2371 *pulTypeNumber = ulTypeNumber;
2372 // look for symbols address in external symbols
2373 if( pStab->n_type == N_LSYM || pStab->n_type == N_PSYM )
2374 *pValue = CurrentEBP + pStab->n_value;
2375 else *pValue = FindFunctionInModuleByName(SymbolName,pCurrentMod);
2376
2377 DPRINT((0,"value = %x\n",*pValue));
2378 *pulFileNumber = ulCurrentFileNumber;
2379 DPRINT((0,"file = %x\n",ulCurrentFileNumber));
2380 if((pTypeDefIncluded = PICE_strchr(pName,'=')) )
2381 {
2382 DPRINT((0,"symbol includes type definition (%s)\n",pTypeDefIncluded));
2383 }
2384 return TRUE;
2385 }
2386 break;
2387 }
2388 pStab++;
2389 }
2390 }
2391 }
2392 return FALSE;
2393 }
2394
2395 //*************************************************************************
2396 // ExtractToken()
2397 //
2398 //*************************************************************************
2399 void ExtractToken(LPSTR pStringToken)
2400 {
2401 while(PICE_isalpha(pExpression[ulIndex]) || PICE_isdigit(pExpression[ulIndex]) || pExpression[ulIndex]=='_')
2402 {
2403 *pStringToken++=pExpression[ulIndex++];
2404 *pStringToken=0;
2405 }
2406 }
2407
2408 //*************************************************************************
2409 // ExtractTypeName()
2410 //
2411 //*************************************************************************
2412 LPSTR ExtractTypeName(LPSTR p)
2413 {
2414 static char temp[1024];
2415 ULONG i;
2416
2417 DPRINT((1,"ExtractTypeName(%s)\n",p));
2418
2419 for(i=0;IsAddressValid((ULONG)p) && *p!=0 && *p!=':';i++,p++)
2420 temp[i] = *p;
2421
2422 if(!IsAddressValid((ULONG)p) )
2423 {
2424 DPRINT((1,"hit invalid page %x!\n",(ULONG)p));
2425 }
2426
2427 temp[i]=0;
2428
2429 return temp;
2430 }
2431
2432 //*************************************************************************
2433 // ExtractNumber()
2434 //
2435 //*************************************************************************
2436 LONG ExtractNumber(LPSTR p)
2437 {
2438 LONG lMinus = 1,lBase;
2439 ULONG lNumber = 0;
2440
2441 DPRINT((0,"ExtractNumber(): %s\n",p));
2442
2443 if(!IsAddressValid((ULONG)p) )
2444 {
2445 DPRINT((1,"ExtractNumber(): [1] invalid page %x hit!\n",p));
2446 return 0;
2447 }
2448
2449 if(*p == '-')
2450 {
2451 lMinus = -1;
2452 p++;
2453 }
2454
2455 if(!IsAddressValid((ULONG)p) )
2456 {
2457 DPRINT((1,"ExtractNumber(): [2] invalid page %x hit!\n",p));
2458 return 0;
2459 }
2460
2461 if(*p != '0') // non-octal -> decimal number
2462 lBase = 10;
2463 else
2464 lBase = 8;
2465
2466 if(!IsAddressValid((ULONG)p) )
2467 {
2468 DPRINT((1,"ExtractNumber(): [3] invalid page %x hit!\n",p));
2469 return 0;
2470 }
2471
2472 while(PICE_isdigit(*p))
2473 {
2474 lNumber *= lBase;
2475 lNumber += *p-'0';
2476 p++;
2477 if(!IsAddressValid((ULONG)p) )
2478 {
2479 DPRINT((1,"ExtractNumber(): [4] invalid page %x hit!\n",p));
2480 return 0;
2481 }
2482 }
2483
2484 return (lNumber*lMinus);
2485 }
2486
2487 //*************************************************************************
2488 // ExtractArray()
2489 //
2490 //*************************************************************************
2491 BOOLEAN ExtractArray(PVRET pvr,LPSTR p)
2492 {
2493 ULONG index_typenumber,type_number;
2494 ULONG lower_bound,upper_bound;
2495 LPSTR pTypeDef;
2496
2497 DPRINT((1,"ExtractArray(%s)\n",p));
2498
2499 // index-type index-type-number;lower;upper;element-type-number
2500 pvr->bArrayType = TRUE;
2501 p++;
2502 index_typenumber = ExtractTypeNumber(p);
2503 p = PICE_strchr(p,';');
2504 if(p)
2505 {
2506 p++;
2507 lower_bound = ExtractNumber(p);
2508 p = PICE_strchr(p,';');
2509 if(p)
2510 {
2511 p++;
2512
2513 upper_bound = ExtractNumber(p);
2514 p = PICE_strchr(p,';');
2515 if(p)
2516 {
2517 p++;
2518
2519 type_number = ExtractTypeNumber(p);
2520
2521 DPRINT((1,"ExtractArray(): %x %x %x %x\n",index_typenumber,lower_bound,upper_bound,type_number));
2522
2523 pTypeDef = FindTypeDefinition(pvr->pSymbols,type_number,pvr->file);
2524 if(pTypeDef)
2525 {
2526 PICE_strcpy(pvr->type_name,ExtractTypeName(pTypeDef));
2527 pvr->type = type_number;
2528 return TRUE;
2529 }
2530 }
2531 }
2532 }
2533 return FALSE;
2534 }
2535
2536 //*************************************************************************
2537 // ExtractStructMembers()
2538 //
2539 //*************************************************************************
2540 PVRET ExtractStructMembers(PVRET pvr,LPSTR p)
2541 {
2542 ULONG len;
2543 static char member_name[128];
2544 LONG bit_offset,bit_size,type_number,byte_size;
2545 static VRET vr;
2546 LPSTR pTypeDef,pEqual;
2547
2548 DPRINT((1,"ExtractStructMembers(): %s\n",p));
2549
2550 PICE_memset(&vr,0,sizeof(vr));
2551
2552 // name:type-number,bit-offset,bit-size
2553 len=StrLenUpToWhiteChar(p,":");
2554 if(len)
2555 {
2556 // extract member name
2557 PICE_strncpy(member_name,p,len);
2558 member_name[len]=0;
2559 DPRINT((1,"ExtractStructMembers(): member_name = %s\n",member_name));
2560
2561 // go to char following ':'
2562 p += (len+1);
2563 if(IsAddressValid((ULONG)p) )
2564 {
2565 type_number = ExtractTypeNumber(p);
2566 DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number));
2567
2568 vr.type = type_number;
2569
2570 pEqual = PICE_strchr(p,')');
2571 // see if it includes type def
2572 if(pEqual)
2573 {
2574 p = pEqual+1;
2575 if(*p == '=')
2576 {
2577 p++;
2578 if(*p == 'a')
2579 {
2580 DPRINT((1,"ExtractStructMembers(): member is array\n"));
2581 vr.bArrayType = TRUE;
2582 p = PICE_strchr(p,';');
2583 p = PICE_strchr(p,';');
2584 p = PICE_strchr(p,';');
2585 if(p)
2586 p++;
2587
2588 type_number = ExtractTypeNumber(p);
2589 vr.father_type = type_number;
2590 }
2591 else if(*p == '*')
2592 {
2593 DPRINT((1,"ExtractStructMembers(): member is ptr\n"));
2594 vr.bPtrType = TRUE;
2595 type_number = ExtractTypeNumber(p);
2596 DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number));
2597 vr.father_type = type_number;
2598 }
2599 else if(*p == 'u')
2600 {
2601 DPRINT((1,"ExtractStructMembers(): member is union\n"));
2602 while(*p!=';' && *(p+1)!=';' && *p!=0)p++;
2603 }
2604 }
2605 }
2606
2607 p = PICE_strchr(p,',');
2608 if(p)
2609 {
2610 p++;
2611 bit_offset = ExtractNumber(p);
2612 DPRINT((1,"ExtractStructMembers(): bit_offset = %x\n",bit_offset));
2613 p = PICE_strchr(p,',');
2614 if(p)
2615 {
2616 p++;
2617
2618 bit_size = ExtractNumber(p);
2619 DPRINT((1,"ExtractStructMembers(): bit_size = %x\n",bit_size));
2620
2621 vr.address = pvr->value + bit_offset/8;
2622 vr.file = pvr->file;
2623 vr.size = bit_size;
2624 PICE_strcpy(vr.name,member_name);
2625 byte_size = (bit_size+1)/8;
2626 if(!byte_size)
2627 byte_size = 4;
2628 pvr->address = pvr->value;
2629 if(IsRangeValid(vr.address,byte_size))
2630 {
2631 switch(byte_size)
2632 {
2633 case 1:
2634 vr.value = *(PUCHAR)vr.address;
2635 break;
2636 case 2:
2637 vr.value = *(PUSHORT)vr.address;
2638 break;
2639 case 4:
2640 vr.value = *(PULONG)vr.address;
2641 break;
2642 }
2643 }
2644
2645 DPRINT((1,"ExtractStructMembers(): member %s type %x bit_offset %x bit_size%x\n",member_name,type_number,bit_offset,bit_size));
2646
2647 pTypeDef = FindTypeDefinition(pvr->pSymbols,type_number,pvr->file);
2648 if(pTypeDef)
2649 {
2650 DPRINT((1,"ExtractStructMembers(): pTypedef= %s\n",pTypeDef));
2651 PICE_strcpy(vr.type_name,ExtractTypeName(pTypeDef));
2652 pTypeDef = PICE_strchr(pTypeDef,':');
2653 if(pTypeDef)
2654 {
2655 pTypeDef++;
2656 type_number = ExtractTypeNumber(pTypeDef);
2657 DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number));
2658 vr.father_type = type_number;
2659 }
2660 }
2661 }
2662 }
2663 }
2664 }
2665
2666 return &vr;
2667 }
2668
2669 //*************************************************************************
2670 // EvaluateSymbol()
2671 //
2672 //*************************************************************************
2673 BOOLEAN EvaluateSymbol(PVRET pvr,LPSTR pToken)
2674 {
2675 LPSTR pTypeDef,pTypeName,pTypeBase,pSemiColon,pStructMembers;
2676 BOOLEAN bDone = FALSE;
2677 ULONG ulType,ulBits,ulBytes;
2678 LONG lLowerRange,lUpperRange,lDelta;
2679 static char type_def[2048];
2680
2681 DPRINT((1,"EvaluateSymbol(%s)\n",pToken));
2682
2683 if(FindGlobalStabSymbol(pToken,&pvr->value,&pvr->type,&pvr->file))
2684 {
2685 DPRINT((1,"EvaluateSymbol(%s) pvr->value = %x pvr->type = %x\n",pToken,pvr->value,pvr->type));
2686 while(!bDone)
2687 {
2688 if(!(pTypeDef = FindTypeDefinition(pvr->pSymbols,pvr->type,pvr->file)))
2689 break;
2690 PICE_strcpy(type_def,pTypeDef);
2691
2692 pTypeDef = type_def;
2693
2694 pTypeName = ExtractTypeName(pTypeDef);
2695
2696 DPRINT((1,"%s %s\n",pTypeName,pToken));
2697
2698 PICE_strcpy(pvr->type_name,pTypeName);
2699
2700 pTypeBase = PICE_strchr(pTypeDef,'=');
2701
2702 if(!pTypeBase)
2703 return FALSE;
2704
2705 pTypeBase++;
2706
2707 switch(*pTypeBase)
2708 {
2709 case '(': // type reference
2710 ulType = ExtractTypeNumber(pTypeBase);
2711 DPRINT((1,"%x is a type reference to %x\n",pvr->type,ulType));
2712 pvr->type = ulType;
2713 break;
2714 case 'r': // subrange
2715 pTypeBase++;
2716 ulType = ExtractTypeNumber(pTypeBase);
2717 DPRINT((1,"%x is sub range of %x\n",pvr->type,ulType));
2718 if(pvr->type == ulType)
2719 {
2720 DPRINT((1,"%x is a self reference\n",pvr->type));
2721 pSemiColon = PICE_strchr(pTypeBase,';');
2722 pSemiColon++;
2723 lLowerRange = ExtractNumber(pSemiColon);
2724 pSemiColon = PICE_strchr(pSemiColon,';');
2725 pSemiColon++;
2726 lUpperRange = ExtractNumber(pSemiColon);
2727 lDelta = lUpperRange-lLowerRange;
2728 DPRINT((1,"bounds %x-%x range %x\n",lLowerRange,lUpperRange,lDelta));
2729 ulBits=0;
2730 do
2731 {
2732 ulBits++;
2733 lDelta /= 2;
2734 }while(lDelta);
2735 ulBytes = (ulBits+1)/8;
2736 if(!ulBytes)
2737 ulBytes = 4;
2738 DPRINT((1,"# of bytes = %x\n",ulBytes));
2739 pvr->address = pvr->value;
2740 if(IsRangeValid(pvr->value,ulBytes))
2741 {
2742 switch(ulBytes)
2743 {
2744 case 1:
2745 pvr->value = *(PUCHAR)pvr->value;
2746 break;
2747 case 2:
2748 pvr->value = *(PUSHORT)pvr->value;
2749 break;
2750 case 4:
2751 pvr->value = *(PULONG)pvr->value;
2752 break;
2753 }
2754 }
2755 bDone=TRUE;
2756 }
2757 else
2758 pvr->type = ulType;
2759 break;
2760 case 'a': // array type
2761 DPRINT((1,"%x array\n",pvr->type));
2762 pTypeBase++;
2763 if(!ExtractArray(pvr,pTypeBase))
2764 {
2765 bDone = TRUE;
2766 pvr->error = 1;
2767 }
2768 break;
2769 case '*': // ptr type
2770 DPRINT((1,"%x is ptr to\n",pvr->type));
2771 bDone = TRUE; // meanwhile
2772 break;
2773 case 's': // struct type [name:T(#,#)=s#membername1:(#,#),#,#;membername1:(#,#),#,#;;]
2774 // go past 's'
2775 pTypeBase++;
2776
2777 // extract the the struct size
2778 lLowerRange = ExtractNumber(pTypeBase);
2779 DPRINT((1,"%x struct size = %x\n",pvr->type,lLowerRange));
2780
2781 // skip over the digits
2782 while(PICE_isdigit(*pTypeBase))
2783 pTypeBase++;
2784
2785 // the structs address is is value
2786 pvr->address = pvr->value;
2787 pvr->bStructType = TRUE;
2788
2789 // decode the struct members. pStructMembers now points to first member name
2790 pStructMembers = pTypeBase;
2791
2792 while(pStructMembers && *pStructMembers && *pStructMembers!=';' && ulNumStructMembers<DIM(vrStructMembers))
2793 {
2794 DPRINT((1,"EvaluateSymbol(): member #%u\n",ulNumStructMembers));
2795 // put this into our array
2796 vrStructMembers[ulNumStructMembers] = *ExtractStructMembers(pvr,pStructMembers);
2797
2798 if(!PICE_strlen(vrStructMembers[ulNumStructMembers].type_name))
2799 {
2800 ULONG i;
2801 PVRET pvrThis = &vrStructMembers[ulNumStructMembers];
2802
2803 DPRINT((1,"EvaluateSymbol(): no type name\n"));
2804 for(i=0;i<ulNumStructMembers;i++)
2805 {
2806 DPRINT((1,"EvaluateSymbol(): vr[i].type_name = %s\n",vrStructMembers[i].type_name));
2807 DPRINT((1,"EvaluateSymbol(): vr[i].name = %s\n",vrStructMembers[i].name));
2808 DPRINT((1,"EvaluateSymbol(): vr[i].address = %.8X\n",vrStructMembers[i].address));
2809 DPRINT((1,"EvaluateSymbol(): vr[i].value = %.8X\n",vrStructMembers[i].value));
2810 DPRINT((1,"EvaluateSymbol(): vr[i].size = %.8X\n",vrStructMembers[i].size));
2811 DPRINT((1,"EvaluateSymbol(): vr[i].type = %.8X\n",vrStructMembers[i].type));
2812 if(pvrThis->type == vrStructMembers[i].type)
2813 {
2814 PICE_strcpy(pvrThis->type_name,vrStructMembers[i].type_name);
2815 pvrThis->bArrayType = vrStructMembers[i].bArrayType;
2816 pvrThis->bPtrType = vrStructMembers[i].bPtrType;
2817 pvrThis->bStructType = vrStructMembers[i].bStructType;
2818 break;
2819 }
2820 }
2821 }
2822
2823 DPRINT((1,"EvaluateSymbol(): vr.type_name = %s\n",vrStructMembers[ulNumStructMembers].type_name));
2824 DPRINT((1,"EvaluateSymbol(): vr.name = %s\n",vrStructMembers[ulNumStructMembers].name));
2825 DPRINT((1,"EvaluateSymbol(): vr.address = %.8X\n",vrStructMembers[ulNumStructMembers].address));
2826 DPRINT((1,"EvaluateSymbol(): vr.value = %.8X\n",vrStructMembers[ulNumStructMembers].value));
2827 DPRINT((1,"EvaluateSymbol(): vr.size = %.8X\n",vrStructMembers[ulNumStructMembers].size));
2828 DPRINT((1,"EvaluateSymbol(): vr.type = %.8X\n",vrStructMembers[ulNumStructMembers].type));
2829
2830 ulNumStructMembers++;
2831
2832 // skip to next ':'
2833 pStructMembers = PICE_strchr(pStructMembers,';');
2834 pStructMembers = PICE_strchr(pStructMembers,':');
2835 if(pStructMembers)
2836 {
2837 DPRINT((1,"EvaluateSymbol(): ptr is now %s\n",pStructMembers));
2838 // go back to where member name starts
2839 while(*pStructMembers!=';')
2840 pStructMembers--;
2841 // if ';' present, go to next char
2842 if(pStructMembers)
2843 pStructMembers++;
2844 }
2845 }
2846
2847 bDone = TRUE; // meanwhile
2848 break;
2849 case 'u': // union type
2850 DPRINT((1,"%x union\n",pvr->type));
2851 bDone = TRUE; // meanwhile
2852 break;
2853 case 'e': // enum type
2854 DPRINT((1,"%x enum\n",pvr->type));
2855 bDone = TRUE; // meanwhile
2856 break;
2857 default:
2858 DPRINT((1,"DEFAULT %x, base: %c\n",pvr->type, *pTypeBase));
2859 pvr->address = pvr->value;
2860 if(IsRangeValid(pvr->value,ulBytes))
2861 {
2862 switch(ulBytes)
2863 {
2864 case 1:
2865 pvr->value = *(PUCHAR)pvr->value;
2866 break;
2867 case 2:
2868 pvr->value = *(PUSHORT)pvr->value;
2869 break;
2870 case 4:
2871 pvr->value = *(PULONG)pvr->value;
2872 break;
2873 }
2874 }
2875 bDone = TRUE;
2876 break;
2877 }
2878
2879 }
2880 return TRUE;
2881 }
2882 return FALSE;
2883 }
2884
2885 //*************************************************************************
2886 // Symbol()
2887 //
2888 // Symbol := v
2889 //*************************************************************************
2890 BOOLEAN Symbol(PVRET pvr)
2891 {
2892 char SymbolToken[128];
2893
2894 ExtractToken(SymbolToken);
2895
2896 DPRINT((1,"SymbolToken = %s\n",SymbolToken));
2897
2898 return EvaluateSymbol(pvr,SymbolToken);
2899 }
2900
2901 //*************************************************************************
2902 // Expression()
2903 //
2904 // Expression := Symbol | Symbol->Symbol
2905 //*************************************************************************
2906 BOOLEAN Expression(PVRET pvr)
2907 {
2908 if(!Symbol(pvr))
2909 return FALSE;
2910
2911 return TRUE;
2912 }
2913
2914 //*************************************************************************
2915 // Evaluate()
2916 //
2917 //*************************************************************************
2918 void Evaluate(PICE_SYMBOLFILE_HEADER* pSymbols,LPSTR p)
2919 {
2920 ULONG i;
2921
2922 PICE_memset(&vr,0,sizeof(vr));
2923 vr.pSymbols = pSymbols;
2924
2925 pExpression = p;
2926 ulIndex=0;
2927 ulNumStructMembers=0;
2928 if(Expression(&vr))
2929 {
2930 DPRINT((1,"\nOK!\n"));
2931 DPRINT((1,"value = %x type = %x\n",vr.value,vr.type));
2932 if(vr.bStructType)
2933 {
2934 PICE_sprintf(tempSym,"struct %s %s @ %x\n",vr.type_name,p,vr.address);
2935 Print(OUTPUT_WINDOW,tempSym);
2936 for(i=0;i<ulNumStructMembers;i++)
2937 {
2938 if(vrStructMembers[i].bArrayType)
2939 {
2940 PICE_sprintf(tempSym,"[%.8X %.8X] %s %s[%u]\n",
2941 vrStructMembers[i].address,
2942 vrStructMembers[i].size/8,
2943 vrStructMembers[i].type_name,
2944 vrStructMembers[i].name,
2945 vrStructMembers[i].size/8);
2946 }
2947 else if(vrStructMembers[i].bPtrType)
2948 {
2949 PICE_sprintf(tempSym,"[%.8X %.8X] %s* %s -> %x (%u)\n",
2950 vrStructMembers[i].address,
2951 vrStructMembers[i].size/8,
2952 vrStructMembers[i].type_name,
2953 vrStructMembers[i].name,
2954 vrStructMembers[i].value,
2955 vrStructMembers[i].value);
2956 }
2957 else
2958 {
2959 PICE_sprintf(tempSym,"[%.8X %.8X] %s %s = %x (%u)\n",
2960 vrStructMembers[i].address,
2961 vrStructMembers[i].size/8,
2962 vrStructMembers[i].type_name,
2963 vrStructMembers[i].name,
2964 vrStructMembers[i].value,
2965 vrStructMembers[i].value);
2966 }
2967 Print(OUTPUT_WINDOW,tempSym);
2968 }
2969 }
2970 else if(vr.bArrayType)
2971 {
2972 Print(OUTPUT_WINDOW,"array\n");
2973 }
2974 else
2975 {
2976 PICE_sprintf(tempSym,"%s %s @ %x = %x (%u)\n",vr.type_name,p,vr.address,vr.value,vr.value);
2977 Print(OUTPUT_WINDOW,tempSym);
2978 }
2979 }
2980 else
2981 {
2982 DPRINT((1,"\nERROR: code %x\n",vr.error));
2983 }
2984 }