3 Copyright (c) 1998-2001 Klaus P. Gerlicher
18 Reactos Port by Eugene Ingerman
23 15-Nov-2000: general cleanup of source files
27 This file may be distributed under the terms of the GNU Public License.
31 ////////////////////////////////////////////////////
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>
51 LOCAL_VARIABLE local_vars
[512];
53 PICE_SYMBOLFILE_HEADER
* apSymbols
[32]={NULL
,};
54 ULONG ulNumSymbolsLoaded
=0;
58 char tempSym
[1024]; // temp buffer for output
89 PICE_SYMBOLFILE_HEADER
* pSymbols
;
95 VRET vrStructMembers
[1024];
96 ULONG ulNumStructMembers
;
98 BOOLEAN
Expression(PVRET pvr
);
100 LIST_ENTRY
*pModuleListHead
= NULL
;
101 extern PDIRECTORY_OBJECT
*pNameSpaceRoot
;
102 extern PDEBUG_MODULE pdebug_module_tail
;
103 extern PDEBUG_MODULE pdebug_module_head
;
106 PVOID
HEADER_TO_BODY(POBJECT_HEADER obj
)
108 return(((void *)obj
)+sizeof(OBJECT_HEADER
)-sizeof(COMMON_BODY_HEADER
));
111 POBJECT_HEADER
BODY_TO_HEADER(PVOID body
)
113 PCOMMON_BODY_HEADER chdr
= (PCOMMON_BODY_HEADER
)body
;
114 return(CONTAINING_RECORD((&(chdr
->Type
)),OBJECT_HEADER
,Type
));
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
)
123 PDEBUG_MODULE pNext
= pm
;
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
)
141 PDEBUG_MODULE pNext
= NULL
, pm
= *ppmodule
;
148 pm
= (PDEBUG_MODULE
)ExAllocatePool( NonPagedPool
, sizeof( DEBUG_MODULE
) );
150 FreeModuleList(pNext
);
155 pm
->BaseAddress
= NULL
;
156 //DbgPrint("len1: %d\n", pm->name.Length);
166 BOOLEAN
ListUserModules( PPEB peb
)
168 PLIST_ENTRY UserModuleListHead
;
170 PLDR_DATA_TABLE_ENTRY Module
;
176 if( Ldr
&& IsAddressValid((ULONG
)Ldr
)){
177 UserModuleListHead
= &Ldr
->InLoadOrderModuleList
;
178 ASSERT(IsAddressValid((ULONG
)UserModuleListHead
));
179 Entry
= UserModuleListHead
->Flink
;
180 while (Entry
!= UserModuleListHead
)
182 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderModuleList
);
183 //DbgPrint("Module: %x, BaseAddress: %x\n", Module, Module->BaseAddress);
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
));
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
;
195 Entry
= Entry
->Flink
;
202 POBJECT
FindDriverObjectDirectory( void )
205 POBJECT_HEADER current_obj
;
206 PDIRECTORY_OBJECT pd
;
210 if( pNameSpaceRoot
&& *pNameSpaceRoot
){
211 current
= (*pNameSpaceRoot
)->head
.Flink
;
212 while (current
!=(&((*pNameSpaceRoot
)->head
)))
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)
218 pd
=HEADER_TO_BODY(current_obj
);
219 DPRINT((0,"Found it %x\n",pd
));
222 current
= current
->Flink
;
229 BOOLEAN
ListDriverModules( void )
231 PLIST_ENTRY current_entry
;
232 PMODULE_OBJECT current
;
233 POBJECT_HEADER current_obj
;
237 ASSERT( pModuleListHead
);
239 current_entry
= pModuleListHead
->Flink
;
241 while (current_entry
!= (pModuleListHead
)){
243 current
= CONTAINING_RECORD(current_entry
,MODULE_OBJECT
,ListEntry
);
245 DPRINT((0,"FullName: %S, BaseName: %S, Length: %ld, EntryPoint: %x\n", current
->FullName
.Buffer
,
246 current
->BaseName
.Buffer
, current
->Length
, current
->EntryPoint
));
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
;
253 pdebug_module_tail
= pdebug_module_tail
->next
;
255 if (current
&& _wcsicmp(current
->BaseName
.Buffer
, L
"ntoskrnl")==0)
257 kernel_end
= (ULONG
)current
->Base
+ current
->Length
;
259 current_entry
= current_entry
->Flink
;
266 BOOLEAN
BuildModuleList( void )
272 pdebug_module_tail
= pdebug_module_head
;
273 tsk
= IoGetCurrentProcess();
274 ASSERT(IsAddressValid((ULONG
)tsk
));
278 if( !ListUserModules( peb
) ){
284 if( !ListDriverModules() ){
292 //*************************************************************************
295 //*************************************************************************
296 PDEBUG_MODULE
IsModuleLoaded(LPSTR p
)
301 DPRINT((0,"IsModuleLoaded(%s)\n",p
));
303 if(BuildModuleList())
305 pd
= pdebug_module_head
;
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)
313 DPRINT((0,"module %S is loaded!\n",pd
->name
));
317 }while((pd
= pd
->next
)!=pdebug_module_tail
);
323 //*************************************************************************
326 //*************************************************************************
327 BOOLEAN
ScanExports(const char *pFind
,PULONG pValue
)
331 LPSTR pExp
= pExports
;
332 BOOLEAN bResult
= FALSE
;
335 DPRINT((0,"ScanExports pValue: %x\n", pValue
));
338 pStr
= strstr(pExp
,pFind
);
344 LPSTR pOldStr
= pStr
;
346 for(;(*pStr
!=0x0a && *pStr
!=0x0d) && (ULONG
)pStr
>=(ULONG
)pExports
;pStr
--);
349 for(;(*pStr
!=0x0a && *pStr
!=0x0d);)*p
++=*pStr
++;
351 p
= (LPSTR
) PICE_strtok(temp
," ");
358 ConvertTokenToHex(p
,pValue
);
363 if(strcmp(p
,pFind
)!=0)
365 DPRINT((0,"Not: %s\n", p
));
371 DPRINT((0,"%s @ %x\n",pFind
,*pValue
));
376 p
= (char*) PICE_strtok(NULL
," ");
380 DPRINT((0,"%s %x @ %x\n",pFind
,pValue
,*pValue
));
387 //*************************************************************************
390 //*************************************************************************
391 BOOLEAN
ReadHex(LPSTR p
,PULONG pValue
)
395 for(i
=0;i
<8 && p
[i
]!=0 && p
[i
]!=' ';i
++)
397 if(p
[i
]>='0' && p
[i
]<='9')
400 result
|=(ULONG
)(UCHAR
)(p
[i
]-'0');
402 else if(p
[i
]>='A' && p
[i
]<='F')
405 result
|=(ULONG
)(UCHAR
)(p
[i
]-'A'+10);
407 else if(p
[i
]>='a' && p
[i
]<='f')
410 result
|=(ULONG
)(UCHAR
)(p
[i
]-'a'+10);
420 //*************************************************************************
423 //*************************************************************************
424 BOOLEAN
ScanExportLine(LPSTR p
,PULONG ulValue
,LPSTR
* ppPtrToSymbol
)
426 BOOLEAN bResult
= FALSE
;
428 if(ReadHex(p
,ulValue
))
431 *ppPtrToSymbol
+= 11;
438 //*************************************************************************
439 // ValidityCheckSymbols()
441 //*************************************************************************
442 BOOLEAN
ValidityCheckSymbols(PICE_SYMBOLFILE_HEADER
* pSymbols
)
446 DPRINT((0,"ValidityCheckSymbols()\n"));
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
));
454 DPRINT((0,"ValidityCheckSymbols(): symbols are %s\n",bRet
?"VALID":"NOT VALID"));
459 //*************************************************************************
460 // FindModuleSymbols()
462 //*************************************************************************
463 PICE_SYMBOLFILE_HEADER
* FindModuleSymbols(ULONG addr
)
466 PDEBUG_MODULE pd
= pdebug_module_head
;
468 DPRINT((0,"FindModuleSymbols(%x)\n",addr
));
469 if(BuildModuleList())
472 pd
= pdebug_module_head
;
475 DPRINT((0,"pd: %x\n", pd
));
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
)
483 DPRINT((0,"FindModuleSymbols(): address matches %S %x-%x\n",pd
->name
,start
,end
));
484 for(i
=0;i
<ulNumSymbolsLoaded
;i
++)
486 DPRINT((0,"%S -", apSymbols
[i
]->name
));
487 if(PICE_wcsicmp(pd
->name
,apSymbols
[i
]->name
) == 0)
489 if(ValidityCheckSymbols(apSymbols
[i
]))
497 }while((pd
= pd
->next
) != pdebug_module_tail
);
503 //*************************************************************************
504 // FindModuleFromAddress()
506 //*************************************************************************
507 PDEBUG_MODULE
FindModuleFromAddress(ULONG addr
)
512 DPRINT((0,"FindModuleFromAddress()\n"));
513 if(BuildModuleList())
515 pd
= pdebug_module_head
;
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
)
525 DPRINT((0,"FindModuleFromAddress(): found %S\n",pd
->name
));
529 }while((pd
= pd
->next
)!=pdebug_module_tail
);
535 //*************************************************************************
536 // FindModuleByName()
538 //*************************************************************************
539 PDEBUG_MODULE
FindModuleByName(LPSTR modname
)
542 WCHAR tempstr
[DEBUG_MODULE_NAME_LEN
];
544 DPRINT((0,"FindModuleFromAddress()\n"));
545 if( !PICE_MultiByteToWideChar(CP_ACP
, NULL
, modname
, -1, tempstr
, DEBUG_MODULE_NAME_LEN
) )
547 DPRINT((0,"Can't convert module name.\n"));
551 if(BuildModuleList())
553 pd
= pdebug_module_head
;
558 if(PICE_wcsicmp(tempstr
,pd
->name
) == 0)
560 DPRINT((0,"FindModuleByName(): found %S\n",pd
->name
));
564 }while((pd
= pd
->next
) != pdebug_module_tail
);
570 //*************************************************************************
571 // FindModuleSymbolsByModuleName()
573 //*************************************************************************
574 PICE_SYMBOLFILE_HEADER
* FindModuleSymbolsByModuleName(LPSTR modname
)
577 WCHAR tempstr
[DEBUG_MODULE_NAME_LEN
];
579 DPRINT((0,"FindModuleSymbols()\n"));
580 if( !PICE_MultiByteToWideChar(CP_ACP
, NULL
, modname
, -1, tempstr
, DEBUG_MODULE_NAME_LEN
) )
582 DPRINT((0,"Can't convert module name in FindModuleSymbols.\n"));
586 for(i
=0;i
<ulNumSymbolsLoaded
;i
++)
588 if(PICE_wcsicmp(tempstr
,apSymbols
[i
]->name
) == 0)
595 //*************************************************************************
596 // ScanExportsByAddress()
598 //*************************************************************************
599 BOOLEAN
ScanExportsByAddress(LPSTR
*pFind
,ULONG ulValue
)
602 static char temp3
[256];
603 LPSTR p
,pStartOfLine
,pSymbolName
=NULL
;
604 ULONG ulCurrentValue
=0;
605 BOOLEAN bResult
= FALSE
;
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
612 PIMAGE_SECTION_HEADER pShdr
;
613 PICE_SYMBOLFILE_HEADER
* pSymbols
;
618 DPRINT((0,"In ScanExportsByAddress:\n"));
620 pSymbols
= FindModuleSymbols(ulValue
);
621 DPRINT((0,"pSymbols: %x\n", pSymbols
));
623 if(BuildModuleList()){
624 if(pSymbols
&& pdebug_module_head
)
626 PDEBUG_MODULE pdTemp
;
628 DPRINT((0,"looking up symbols\n"));
629 pd
= pdebug_module_head
;
635 if(ulValue
>=((ULONG
)pdTemp
->BaseAddress
) && ulValue
<((ULONG
)pdTemp
+pdTemp
->size
))
637 if(PICE_wcsicmp(pdTemp
->name
,pSymbols
->name
) == 0)
639 DPRINT((0,"ScanExportsByAddress(): found symbols for module %S @ %x \n",pdTemp
->name
,(ULONG
)pSymbols
));
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
);
646 if(!IsRangeValid((ULONG
)pSym
,sizeof(IMAGE_SYMBOL
) ) ) //should we actually check all the symbols here?
648 DPRINT((0,"ScanExportsByAddress(): pSym = %x is not a valid pointer\n",(ULONG
)pSym
));
652 DPRINT((0,"ScanExportsByAddress(): pSym = %x\n",pSym
));
653 DPRINT((0,"ScanExportsByAddress(): pStr = %x\n",pStr
));
654 DPRINT((0,"ScanExportsByAddress(): pShdr = %x\n",pShdr
));
656 DPRINT((0,"ScanExportsByAddress(): %S has %u symbols\n",pSymbols
->name
,pSymbols
->ulSizeOfGlobals
/sizeof(IMAGE_SYMBOL
)));
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 ))
667 PIMAGE_SECTION_HEADER pShdrThis
= (PIMAGE_SECTION_HEADER
)pShdr
+ (pSym
->SectionNumber
-1);
670 DPRINT((0,"ScanExportsByAddress(): pShdr[%x] = %x\n",pSym
->SectionNumber
,(ULONG
)pShdrThis
));
672 if(!IsRangeValid((ULONG
)pShdrThis
,sizeof(IMAGE_SECTION_HEADER
)) )
674 DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym
->SectionNumber
,(ULONG
)pShdrThis
));
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
));
683 if(ulCurrAddr
<=ulValue
&& ulCurrAddr
>ulAddr
)
689 //skip the auxiliary symbols and get the next symbol
690 pSym
+= pSym
->NumberOfAuxSymbols
+ 1;
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
698 ASSERT(pFoundSym
->N
.Name
.Long
<=pSymbols
->ulSizeOfGlobalsStrings
); //sanity check
699 pName
= pStr
+pFoundSym
->N
.Name
.Long
;
700 if(!IsAddressValid((ULONG
)pName
))
702 DPRINT((0,"ScanExportsByAddress(): pName = %x is not a valid pointer\n",pName
));
705 PICE_sprintf(temp3
,"%S!%s",pdTemp
->name
,pName
);
707 DPRINT((0,"ScanExportsByAddress(): pName = %x\n",(ULONG
)pName
));
712 }while((pd
= pd
->next
));
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
)
720 // while we bound in System.map
721 while(p
<((LPSTR
)pExports
+ulExportLen
))
723 // make a temp ptr to the line we can change
725 // will read the hex value and return a pointer to the symbol name
726 if(ScanExportLine(p
,&ulCurrentValue
,&pStartOfLine
))
728 if(ulValue
>=ulCurrentValue
&& (ulValue
-ulCurrentValue
)<ulMinValue
)
730 // save away our info for later
731 ulMinValue
= ulValue
-ulCurrentValue
;
732 pSymbolName
= pStartOfLine
;
739 // increment pointer to next line
741 while(*p
!=0 && *p
!=0x0a && *p
!=0x0d)p
++;
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
];
751 // decide if we need to append an offset
753 PICE_sprintf(temp3
,"ntoskrnl!%s+%.8X",temp
,ulMinValue
);
755 PICE_sprintf(temp3
,"ntoskrnl!%s",temp
);
763 //*************************************************************************
764 // FindFunctionByAddress()
766 //*************************************************************************
767 LPSTR
FindFunctionByAddress(ULONG ulValue
,PULONG pulstart
,PULONG pulend
)
769 PIMAGE_SYMBOL pSym
, pSymEnd
, pFoundSym
;
771 PIMAGE_SECTION_HEADER pShdr
;
773 PDEBUG_MODULE pdTemp
;
774 PICE_SYMBOLFILE_HEADER
* pSymbols
;
776 static char temp4
[256];
779 pSymbols
= FindModuleSymbols(ulValue
);
780 DPRINT((0,"FindFunctionByAddress(): symbols for %S @ %x \n",pSymbols
->name
,(ULONG
)pSymbols
));
781 if(pSymbols
&& pdebug_module_head
)
783 DPRINT((0,"looking up symbol\n"));
784 pd
= pdebug_module_head
;
790 //initial values for start and end.
791 start
= (ULONG
)pdTemp
->BaseAddress
;
792 end
= start
+pdTemp
->size
;
794 DPRINT((0,"FindFunctionByAddress(): ulValue %x\n",ulValue
));
796 if(ulValue
>=start
&& ulValue
<end
)
798 DPRINT((0,"FindFunctionByAddress(): address matches %S\n",(ULONG
)pdTemp
->name
));
799 if(PICE_wcsicmp(pdTemp
->name
,pSymbols
->name
) == 0)
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
);
807 if(!IsRangeValid((ULONG
)pSym
,sizeof(IMAGE_SYMBOL
) ) ) //should we actually check all the symbols here?
809 DPRINT((0,"FindFunctionByAddress(): pSym = %x is not a valid pointer\n",(ULONG
)pSym
));
812 DPRINT((0,"pSym = %x\n",pSym
));
813 DPRINT((0,"pStr = %x\n",pStr
));
814 DPRINT((0,"pShdr = %x\n",pShdr
));
816 while( pSym
< pSymEnd
)
818 //symbol is a function is it's type is 0x20, and section>0
819 if(( (pSym
->Type
== 0x20) &&
820 (pSym
->SectionNumber
> 0 )))
823 PIMAGE_SECTION_HEADER pShdrThis
= (PIMAGE_SECTION_HEADER
)pShdr
+ (pSym
->SectionNumber
-1);
825 DPRINT((0,"FindFunctionByAddress(): pShdr[%x] = %x\n",pSym
->SectionNumber
,(ULONG
)pShdrThis
));
827 if(!IsRangeValid((ULONG
)pShdrThis
,sizeof(IMAGE_SECTION_HEADER
)) )
829 DPRINT((0,"ScanExportsByAddress(): pElfShdr[%x] = %x is not a valid pointer\n",pSym
->SectionNumber
,(ULONG
)pShdrThis
));
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
));
839 if(ulCurrAddr
<=ulValue
&& ulCurrAddr
>start
)
843 //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for start %x\n",start));
845 else if(ulCurrAddr
>=ulValue
&& ulCurrAddr
<end
)
848 //DPRINT((0,"FindFunctionByAddress(): CANDIDATE for end %x\n",end));
851 //skip the auxiliary symbols and get the next symbol
852 pSym
+= pSym
->NumberOfAuxSymbols
+ 1;
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)
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
;
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
);
874 DPRINT((0,"Function name: %S!%.8s",pdTemp
->name
,pName
));
877 ASSERT(pFoundSym
->N
.Name
.Long
<=pSymbols
->ulSizeOfGlobalsStrings
); //sanity check
878 pName
= pStr
+pFoundSym
->N
.Name
.Long
;
879 if(!IsAddressValid((ULONG
)pName
))
881 DPRINT((0,"FindFunctionByAddress(): pName = %x is not a valid pointer\n",pName
));
884 DPRINT((0,"Function name: %S!%s",pdTemp
->name
,pName
));
889 }while((pd
= pd
->next
) != pdebug_module_tail
);
894 //*************************************************************************
895 // FindDataSectionOffset()
897 //*************************************************************************
899 ULONG FindDataSectionOffset(Elf32_Shdr* pSHdr)
902 DPRINT((0,"FindDataSectionOffset()\n"));
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))
910 return pSHdr->sh_offset;
919 //*************************************************************************
920 // FindFunctionInModuleByNameViaKsyms()
922 //*************************************************************************
923 /* ei: not needed. no Ksyms!
924 ULONG FindFunctionInModuleByNameViaKsyms(struct module* pMod,LPSTR szFunctionname)
932 DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %u symbols for module %s\n",pMod->nsyms,pMod->name));
933 for(i=0;i<pMod->nsyms;i++)
935 DPRINT((0,"FindFunctionInModuleByNameViaKsyms(): %s\n",pMod->syms[i].name));
936 if(PICE_strcmpi((LPSTR)pMod->syms[i].name,szFunctionname) == 0)
938 DPRINT((0,"FindFunctionInModuleByName(): symbol was in exports\n"));
940 return pMod->syms[i].value;
945 DPRINT((0,"FindFunctionInModuleByName(): symbol wasn't in exports\n"));
951 //*************************************************************************
952 // FindFunctionInModuleByName()
954 //*************************************************************************
955 ULONG
FindFunctionInModuleByName(LPSTR szFunctionname
, PDEBUG_MODULE pd
)
958 PICE_SYMBOLFILE_HEADER
* pSymbols
=NULL
;
959 PIMAGE_SYMBOL pSym
, pSymEnd
;
961 PIMAGE_SECTION_HEADER pShdr
;
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
));
968 addr
= (ULONG
)pd
->BaseAddress
;
970 pSymbols
= FindModuleSymbols(addr
);
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
);
979 while( pSym
< pSymEnd
)
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 )))
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 ))
992 PIMAGE_SECTION_HEADER pShdrThis
= (PIMAGE_SECTION_HEADER
)pShdr
+ (pSym
->SectionNumber
-1);
994 start
= ((ULONG
)pd
->BaseAddress
+pShdrThis
->VirtualAddress
+pSym
->Value
);
995 DPRINT((0,"FindFunctionInModuleByName(): %s @ %x\n",szFunctionname
,start
));
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
)
1003 DPRINT((0,"FindFunctionInModuleByName(): symbol was in symbol table, start: %x\n", start
));
1008 pName
= pStr
+pSym
->N
.Name
.Long
;
1009 DPRINT((0,"FindFunctionInModuleByName: %s\n", pName
));
1010 if((PICE_fncmp(pName
,szFunctionname
) == 0) && start
)
1012 DPRINT((0,"FindFunctionInModuleByName(): symbol was in string table, start: %x\n", start
));
1018 //skip the auxiliary symbols and get the next symbol
1019 pSym
+= pSym
->NumberOfAuxSymbols
+ 1;
1026 //*************************************************************************
1027 // ExtractTypeNumber()
1029 //*************************************************************************
1030 ULONG
ExtractTypeNumber(LPSTR p
)
1033 ULONG ulTypeNumber
= 0;
1035 DPRINT((0,"ExtractTypeNumber(%s)\n",p
));
1037 pTypeNumber
= PICE_strchr(p
,'(');
1042 ulTypeNumber
= ExtractNumber(pTypeNumber
);
1043 ulTypeNumber
<<= 16;
1044 pTypeNumber
= PICE_strchr(p
,',');
1048 ulTypeNumber
+= ExtractNumber(pTypeNumber
);
1055 return ulTypeNumber
;
1058 //*************************************************************************
1059 // FindTypeDefinitionForCombinedTypes()
1061 //*************************************************************************
1062 LPSTR
FindTypeDefinitionForCombinedTypes(PICE_SYMBOLFILE_HEADER
* pSymbols
,ULONG ulTypeNumber
,ULONG ulFileNumber
)
1066 LPSTR pStr
,pName
,pTypeNumber
,pTypeDefIncluded
,pNameTemp
;
1068 int nOffset
=0,nNextOffset
=0,nLen
;
1069 static char szAccumulatedName
[2048];
1070 ULONG ulCurrentTypeNumber
,ulCurrentFileNumber
=0;
1071 static char szCurrentPath
[256];
1075 *szAccumulatedName
= 0;
1077 pStab
= (PSTAB_ENTRY
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabs
);
1078 nStabLen
= pSymbols
->ulSizeOfStabs
;
1079 pStr
= (LPSTR
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabsStrings
);
1081 DPRINT((0,"FindTypeDefinitionForCombinedTypes()\n"));
1083 for(i
=0;i
<(nStabLen
/sizeof(STAB_ENTRY
));i
++)
1085 pName
= &pStr
[pStab
->n_strx
+ nOffset
];
1087 switch(pStab
->n_type
)
1090 nOffset
+= nNextOffset
;
1091 nNextOffset
= pStab
->n_value
;
1094 if((nLen
= PICE_strlen(pName
)))
1096 if(pName
[nLen
-1]!='/')
1098 ulCurrentFileNumber
++;
1099 if(PICE_strlen(szCurrentPath
))
1101 PICE_strcat(szCurrentPath
,pName
);
1102 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",szCurrentPath
));
1106 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): changing source file %s\n",pName
));
1110 PICE_strcpy(szCurrentPath
,pName
);
1118 //ei File number count is not reliable
1119 if( 1 /*ulCurrentFileNumber == ulFileNumber*/)
1121 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): %s\n",pName
));
1123 // handle multi-line symbols
1124 if(PICE_strchr(pName
,'\\'))
1126 if(PICE_strlen(szAccumulatedName
))
1128 PICE_strcat(szAccumulatedName
,pName
);
1132 PICE_strcpy(szAccumulatedName
,pName
);
1134 szAccumulatedName
[PICE_strlen(szAccumulatedName
)-1]=0;
1135 //DPRINT((0,"accum. %s\n",szAccumulatedName));
1139 if(PICE_strlen(szAccumulatedName
)==0)
1141 PICE_strcpy(szAccumulatedName
,pName
);
1145 PICE_strcat(szAccumulatedName
,pName
);
1147 pNameTemp
= szAccumulatedName
;
1149 // symbol-name:type-identifier type-number =
1150 nLen
= StrLenUpToWhiteChar(pNameTemp
,":");
1151 if((pTypeDefIncluded
= PICE_strchr(pNameTemp
,'=')) && pNameTemp
[nLen
+1]=='G')
1153 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): symbol includes type definition (%s)\n",pNameTemp
));
1154 pTypeNumber
= pNameTemp
+nLen
+1;
1155 if((ulCurrentTypeNumber
= ExtractTypeNumber(pTypeNumber
)) )
1157 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): type-number %x\n",ulCurrentTypeNumber
));
1158 if(ulCurrentTypeNumber
== ulTypeNumber
)
1160 DPRINT((0,"FindTypeDefinitionForCombinedTypes(): typenumber %x matches!\n",ulCurrentTypeNumber
));
1165 *szAccumulatedName
= 0;
1175 //*************************************************************************
1176 // FindTypeDefinition()
1178 //*************************************************************************
1179 LPSTR
FindTypeDefinition(PICE_SYMBOLFILE_HEADER
* pSymbols
,ULONG ulTypeNumber
,ULONG ulFileNumber
)
1183 LPSTR pStr
,pName
,pTypeString
;
1185 int nOffset
=0,nNextOffset
=0,strLen
;
1186 static char szAccumulatedName
[2048];
1187 ULONG ulCurrentTypeNumber
,ulCurrentFileNumber
=0;
1189 static char szCurrentPath
[256];
1192 DPRINT((0,"FindTypeDefinition(%u,%u)\n",ulTypeNumber
,ulFileNumber
));
1194 *szAccumulatedName
= 0;
1196 pStab
= (PSTAB_ENTRY
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabs
);
1197 nStabLen
= pSymbols
->ulSizeOfStabs
;
1198 pStr
= (LPSTR
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabsStrings
);
1200 for(i
=0;i
<(nStabLen
/sizeof(STAB_ENTRY
));i
++)
1202 pName
= &pStr
[pStab
->n_strx
+ nOffset
];
1204 switch(pStab
->n_type
)
1207 nOffset
+= nNextOffset
;
1208 nNextOffset
= pStab
->n_value
;
1211 if((strLen
= PICE_strlen(pName
)))
1213 if(pName
[strLen
-1]!='/')
1215 ulCurrentFileNumber
++;
1216 if(PICE_strlen(szCurrentPath
))
1218 PICE_strcat(szCurrentPath
,pName
);
1219 DPRINT((0,"FindTypeDefinition()1: cha %s, %u\n",szCurrentPath
, ulCurrentFileNumber
));
1223 DPRINT((0,"FindTypeDefinition(): cha %s, %u\n",pName
, ulCurrentFileNumber
));
1227 PICE_strcpy(szCurrentPath
,pName
);
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*/)
1239 DPRINT((0,"FindTypeDefinition(): pre type definition %s\n",pName
));
1240 // handle multi-line symbols
1241 if(strrchr(pName
,'\\'))
1243 if(PICE_strlen(szAccumulatedName
))
1245 PICE_strcat(szAccumulatedName
,pName
);
1246 DPRINT((0,"FindTypeDefinition(): [1] accum. %s\n",szAccumulatedName
));
1250 PICE_strcpy(szAccumulatedName
,pName
);
1251 DPRINT((0,"FindTypeDefinition(): [2] accum. %s\n",szAccumulatedName
));
1253 szAccumulatedName
[PICE_strlen(szAccumulatedName
)-1]=0;
1257 DPRINT((0,"FindTypeDefinition(): [3] accum. %s, pname: %s\n",szAccumulatedName
, pName
));
1258 if(PICE_strlen(szAccumulatedName
)==0)
1260 PICE_strcpy(szAccumulatedName
,pName
);
1264 PICE_strcat(szAccumulatedName
,pName
);
1266 pTypeString
= szAccumulatedName
;
1268 pTypeSymbol
= PICE_strchr(pTypeString
,':');
1269 if(pTypeSymbol
&& (*(pTypeSymbol
+1)=='t' || *(pTypeSymbol
+1)=='T'))
1272 ulCurrentTypeNumber
= ExtractTypeNumber(pTypeString
);
1273 DPRINT((0,"FindTypeDefinition(): ulCurrType: %u, LSYM is type %s\n",ulCurrentTypeNumber
,pName
));
1274 if(ulCurrentTypeNumber
== ulTypeNumber
)
1276 DPRINT((0,"FindTypeDefinition(): type definition %s\n",pTypeString
));
1280 *szAccumulatedName
=0;
1288 return FindTypeDefinitionForCombinedTypes(pSymbols
,ulTypeNumber
,ulFileNumber
);
1292 //*************************************************************************
1295 //*************************************************************************
1296 LPSTR
TruncateString(LPSTR p
,char c
)
1298 static char temp
[1024];
1303 while(*p
!=0 && *p
!=c
)
1311 //*************************************************************************
1312 // FindLocalsByAddress()
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
)
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;
1331 ULONG ulNumLocalVars
=0;
1333 DPRINT((0,"FindLocalsByAddress()\n"));
1335 pFunctionName
= FindFunctionByAddress(addr
,&start
,&end
);
1336 DPRINT((0,"FindLocalsByAddress(): pFunctionName = %s\n",pFunctionName
));
1339 pSymbols
= FindModuleSymbols(addr
);
1342 pStab
= (PSTAB_ENTRY
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabs
);
1343 nStabLen
= pSymbols
->ulSizeOfStabs
;
1344 pStr
= (LPSTR
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabsStrings
);
1346 for(i
=0;i
<(nStabLen
/sizeof(STAB_ENTRY
));i
++)
1348 pName
= &pStr
[pStab
->n_strx
+ nOffset
];
1350 DPRINT((0,"FindLocalsByAddress(): %x %x %x %x %x\n",
1357 switch(pStab
->n_type
)
1360 nOffset
+= nNextOffset
;
1361 nNextOffset
= pStab
->n_value
;
1364 if((strLen
= PICE_strlen(pName
)))
1366 if(pName
[strLen
-1]!='/')
1368 ulCurrentFileNumber
++;
1369 if(PICE_strlen(szCurrentPath
))
1371 PICE_strcat(szCurrentPath
,pName
);
1372 DPRINT((0,"changing source file1 %s, %u\n",szCurrentPath
,ulCurrentFileNumber
));
1376 DPRINT((0,"changing source file %s, %u\n",pName
,ulCurrentFileNumber
));
1380 PICE_strcpy(szCurrentPath
,pName
);
1388 // if we're in the function we're looking for
1389 if(szCurrentFunction
[0] && PICE_fncmp(szCurrentFunction
,pFunctionName
)==0)
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
)))
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
;
1408 // if we're in the function we're looking for
1409 if(szCurrentFunction
[0] && PICE_fncmp(szCurrentFunction
,pFunctionName
)==0)
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
)))
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
;
1425 // if we're in the function we're looking for
1426 if(szCurrentFunction
[0] && PICE_fncmp(szCurrentFunction
,pFunctionName
)==0)
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
)))
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
;
1444 if(PICE_strlen(pName
))
1448 len
=StrLenUpToWhiteChar(pName
,":");
1449 PICE_strncpy(szCurrentFunction
,pName
,len
);
1450 szCurrentFunction
[len
]=0;
1451 DPRINT((0,"function %s\n",szCurrentFunction
));
1455 DPRINT((0,"END of function %s\n",szCurrentFunction
));
1456 szCurrentFunction
[0]=0;
1459 *local_vars
[ulNumLocalVars
].name
= 0;
1472 //*************************************************************************
1473 // FindSourceLineForAddress()
1475 //*************************************************************************
1476 LPSTR
FindSourceLineForAddress(ULONG addr
,PULONG pulLineNumber
,LPSTR
* ppSrcStart
,LPSTR
* ppSrcEnd
,LPSTR
* ppFilename
)
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
;
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
));
1498 // lookup the modules symbol table (STABS)
1499 pSymbols
= FindModuleSymbols(addr
);
1500 DPRINT((0,"FindSourceLineForAddress: pSymbols %x\n", pSymbols
));
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
)
1508 // prepare STABS access
1509 pStab
= (PSTAB_ENTRY
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabs
);
1510 nStabLen
= pSymbols
->ulSizeOfStabs
;
1511 pStr
= (LPSTR
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabsStrings
);
1513 // walk over all STABS
1514 for(i
=0;i
<(nStabLen
/sizeof(STAB_ENTRY
));i
++)
1516 // the name string corresponding to the STAB
1517 pName
= &pStr
[pStab
->n_strx
+ nOffset
];
1520 switch(pStab
->n_type
)
1522 // change offset of name strings
1524 nOffset
+= nNextOffset
;
1525 nNextOffset
= pStab
->n_value
;
1527 // source file change
1529 DPRINT((0,"changing source file %s\n",pName
));
1530 // if filename has a length record it
1531 if((strLen
= PICE_strlen(pName
)))
1533 PICE_strcpy(szCurrentPath
,pName
);
1535 // else empty filename
1541 // sub-source file change
1543 DPRINT((0,"changing sub source file %s\n",pName
));
1544 // if filename has a length record it
1545 if((strLen
= PICE_strlen(pName
)))
1547 PICE_strcpy(szCurrentPath
,pName
);
1549 // else empty filename
1555 // a function symbol
1557 if(!PICE_strlen(pName
))
1558 {// it's the end of a function
1559 DPRINT((0,"END of function %s\n",szCurrentFunction
));
1561 szCurrentFunction
[0]=0;
1563 // in case we haven't had a zero delta match we return from here
1570 {// if it has a length it's the start of a function
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;
1577 DPRINT((0,"function %s\n",szCurrentFunction
));
1579 //intentional fall through
1583 // if we're in the function we're looking for
1584 if(szCurrentFunction
[0] && PICE_fncmp(szCurrentFunction
,pFunctionName
)==0)
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
))));
1590 PICE_strcpy(szWantedPath
,szCurrentPath
);
1591 DPRINT((0,"source file must be %s\n",szWantedPath
));
1592 bFirstOccurence
= FALSE
;
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 )
1602 PICE_SYMBOLFILE_SOURCE
* pSrc
= (PICE_SYMBOLFILE_SOURCE
*)((ULONG
)pSymbols
+pSymbols
->ulOffsetToSrcFiles
);
1604 DPRINT((0,"code source line number #%u for addr. %x found!\n",pStab
->n_desc
,start
+pStab
->n_value
));
1606 // compute new minimum
1607 ulMinValue
= addr
-(start
+pStab
->n_value
);
1609 // if we have a pointer for storage of line number, store it
1611 *pulLineNumber
= pStab
->n_desc
;
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
));
1617 // for all source files in this module
1618 for(j
=0;j
<pSymbols
->ulNumberOfSrcFiles
;j
++)
1621 ULONG currlen
, fnamelen
;
1623 currlen
= PICE_strlen( szCurrentPath
);
1624 fnamelen
= PICE_strlen( pSrc
->filename
);
1625 pSlash
= pSrc
->filename
+ fnamelen
- currlen
;
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)
1632 ULONG k
= pStab
->n_desc
;
1634 DPRINT((0,"found src file %s @ %x\n",pSrc
->filename
,pSrc
));
1636 // store the pointer to the filename
1638 *ppFilename
= pSrc
->filename
;
1640 if(pSrc
->ulOffsetToNext
> sizeof(PICE_SYMBOLFILE_SOURCE
))
1642 // get a pointer to the source file (right after the file header)
1643 pSrcLine
= (LPSTR
)((ULONG
)pSrc
+sizeof(PICE_SYMBOLFILE_SOURCE
));
1645 // store the source start and end address
1647 *ppSrcStart
= pSrcLine
;
1649 *ppSrcEnd
= pSrcLine
+pSrc
->ulOffsetToNext
-sizeof(PICE_SYMBOLFILE_SOURCE
);
1651 // goto to the right line
1654 while(*pSrcLine
!=0 && *pSrcLine
!=0x0a && *pSrcLine
!=0x0d)
1656 if(!IsAddressValid((ULONG
)pSrcLine
))
1666 DPRINT((0,"src file descriptor found, but contains no source\n"));
1671 (ULONG
)pSrc
+= pSrc
->ulOffsetToNext
;
1681 DPRINT((0,"FindSourceLineForAddress: exit 1\n"));
1685 //*************************************************************************
1686 // FindAddressForSourceLine()
1688 //*************************************************************************
1689 BOOLEAN
FindAddressForSourceLine(ULONG ulLineNumber
,LPSTR pFilename
,PDEBUG_MODULE pMod
,PULONG pValue
)
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
;
1702 DPRINT((0,"FindAddressForSourceLine(%u,%s,%x)\n",ulLineNumber
,pFilename
,(ULONG
)pMod
));
1704 addr
= (ULONG
)pMod
->BaseAddress
;
1706 pSymbols
= FindModuleSymbols(addr
);
1709 pStab
= (PSTAB_ENTRY
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabs
);
1710 nStabLen
= pSymbols
->ulSizeOfStabs
;
1711 pStr
= (LPSTR
)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToStabsStrings
);
1713 for(i
=0;i
<(nStabLen
/sizeof(STAB_ENTRY
));i
++)
1715 pName
= &pStr
[pStab
->n_strx
+ nOffset
];
1717 switch(pStab
->n_type
)
1720 nOffset
+= nNextOffset
;
1721 nNextOffset
= pStab
->n_value
;
1724 if((strLen
= PICE_strlen(pName
)))
1726 if(pName
[strLen
-1]!='/')
1728 if(PICE_strlen(szCurrentPath
))
1730 PICE_strcat(szCurrentPath
,pName
);
1731 DPRINT((0,"changing source file %s\n",szCurrentPath
));
1735 DPRINT((0,"changing source file %s\n",pName
));
1736 PICE_strcpy(szCurrentPath
,pName
);
1740 PICE_strcpy(szCurrentPath
,pName
);
1748 // if we're in the function we're looking for
1749 if(PICE_strcmpi(pFilename
,szCurrentPath
)==0)
1751 if(pStab
->n_desc
>=ulLineNumber
&& (pStab
->n_desc
-ulLineNumber
)<=ulMinValue
)
1753 ulMinValue
= pStab
->n_desc
-ulLineNumber
;
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
);
1759 *pValue
= addr
+ pStab
->n_value
;
1766 if(PICE_strlen(pName
))
1770 len
=StrLenUpToWhiteChar(pName
,":");
1771 PICE_strncpy(szCurrentFunction
,pName
,len
);
1772 szCurrentFunction
[len
]=0;
1773 DPRINT((0,"function %s\n",szCurrentFunction
));
1777 DPRINT((0,"END of function %s\n",szCurrentFunction
));
1778 szCurrentFunction
[0]=0;
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
)
1794 PIMAGE_SYMBOL pSym
, pSymEnd
;
1796 PIMAGE_SECTION_HEADER pShdr
;
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
);
1807 while( pSym
< pSymEnd
)
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 ))
1815 PIMAGE_SECTION_HEADER pShdrThis
= (PIMAGE_SECTION_HEADER
)pShdr
+ (pSym
->SectionNumber
-1);
1816 ULONG section_flags
;
1819 DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x\n",pSym
->SectionNumber
,(ULONG
)pShdrThis
));
1821 if(!IsRangeValid((ULONG
)pShdrThis
,sizeof(IMAGE_SECTION_HEADER
)) )
1823 DPRINT((0,"ListSymbolStartingAt(): pShdr[%x] = %x is not a valid pointer\n",pSym
->SectionNumber
,(ULONG
)pShdrThis
));
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
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
);
1837 ASSERT(pSym
->N
.Name
.Long
<=pSymbols
->ulSizeOfGlobalsStrings
); //sanity check
1838 pName
= pStr
+pSym
->N
.Name
.Long
;
1839 if(!IsAddressValid((ULONG
)pName
))
1841 DPRINT((0,"ListSymbolStartingAt(): pName = %x is not a valid pointer\n",pName
));
1844 PICE_sprintf(pOutput
,"%.8X (%s) %s\n",start
,(section_flags
&IMAGE_SCN_CNT_CODE
)?"TEXT":"DATA",pName
);
1847 if((pSym
+pSym
->NumberOfAuxSymbols
+1)<(pSymEnd
))
1848 return (index
+pSym
->NumberOfAuxSymbols
+1);
1850 index
+= pSym
->NumberOfAuxSymbols
+ 1;
1851 pSym
+= pSym
->NumberOfAuxSymbols
+ 1;
1856 //*************************************************************************
1857 // SanityCheckExports()
1859 //*************************************************************************
1860 BOOLEAN
SanityCheckExports(void)
1862 BOOLEAN bResult
= FALSE
;
1863 ULONG i
,ulValue
,incr
;
1865 Print(OUTPUT_WINDOW
,"pICE: sanity-checking exports...\n");
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)
1870 incr = (fake_kernel_module.nsyms/4);
1872 for(i=0;i<fake_kernel_module.nsyms;i+=incr)
1874 if(ScanExports((char*)fake_kernel_module.syms[i].name,&ulValue) )
1878 ClrLine(wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
1879 PICE_sprintf(tempSym,"pICE: sanity-checking exports %u/%u",
1881 fake_kernel_module.nsyms);
1882 PutChar(tempSym,1,wWindow[OUTPUT_WINDOW].y + wWindow[OUTPUT_WINDOW].usCurY);
1885 if(fake_kernel_module.syms[i].value != ulValue)
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,
1891 Print(OUTPUT_WINDOW,tempSym);
1905 //*************************************************************************
1908 //*************************************************************************
1909 BOOLEAN
LoadExports(void)
1912 BOOLEAN bResult
= TRUE
;
1916 Print(OUTPUT_WINDOW
,"pICE: loading exports...\n");
1917 hf
= PICE_open(L
"\\SystemRoot\\symbols\\ntoskrnl.map",OF_READ
);
1921 Print(OUTPUT_WINDOW,"pICE: no System.map in /boot\n");
1922 hf = PICE_open("/System.map",OF_READ);
1928 //mm_segment_t oldfs;
1934 DPRINT((0,"file len = %d\n",len
));
1936 pExports
= PICE_malloc(len
+1,NONPAGEDPOOL
); // maybe make pool setting an option
1938 DPRINT((0,"pExports = %x\n",pExports
));
1942 //oldfs = get_fs(); set_fs(KERNEL_DS);
1944 ((PUCHAR
)pExports
)[len
]=0;
1945 if(len
== PICE_read(hf
,pExports
,len
))
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
);
1952 DbgPrint("error reading ntoskrnl map!\n");
1960 Print(OUTPUT_WINDOW
,"pICE: no ntoskrnl.sys \n");
1961 Print(OUTPUT_WINDOW
,"pICE: could not load exports...\n");
1970 //*************************************************************************
1973 //*************************************************************************
1974 void UnloadExports(void)
1979 DPRINT((0,"freeing %x\n",pExports
));
1980 PICE_free(pExports
);
1986 //*************************************************************************
1989 //*************************************************************************
1990 PICE_SYMBOLFILE_HEADER
* LoadSymbols(LPSTR filename
)
1993 PICE_SYMBOLFILE_HEADER
* pSymbols
=NULL
;
1998 if( !( conv
= PICE_MultiByteToWideChar(CP_ACP
, NULL
, filename
, -1, tempstr
, 256 ) ) )
2000 DPRINT((0,"Can't convert module name.\n"));
2003 DPRINT((0,"LoadSymbols: filename %s, tempstr %S, conv: %d\n", filename
, tempstr
, conv
));
2005 if(ulNumSymbolsLoaded
<DIM(apSymbols
))
2007 hf
= PICE_open(tempstr
,OF_READ
);
2008 DPRINT((0,"LoadSymbols: hf: %x, file: %S\n",hf
, tempstr
));
2011 //mm_segment_t oldfs;
2014 DPRINT((0,"hf = %x\n",hf
));
2017 DPRINT((0,"file len = %d\n",len
));
2021 pSymbols
= PICE_malloc(len
+1,NONPAGEDPOOL
); // maybe make pool setting an option
2022 DPRINT((0,"pSymbols = %x\n",pSymbols
));
2026 //oldfs = get_fs(); set_fs(KERNEL_DS);
2027 if(len
== PICE_read(hf
,(PVOID
)pSymbols
,len
))
2029 DPRINT((0,"LoadSymbols(): success reading symbols!\n"));
2030 DPRINT((0,"LoadSymbols(): pSymbols->magic = %X\n",pSymbols
->magic
));
2035 if(pSymbols
->magic
== PICE_MAGIC
)
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
;
2050 DPRINT((0,"LoadSymbols(): freeing %x\n",pSymbols
));
2051 DPRINT((0,"pICE: symbols file \"%s\" corrupt\n",filename
));
2052 PICE_free(pSymbols
);
2061 DPRINT((0,"pICE: could not load symbols for %s...\n",filename
));
2070 //*************************************************************************
2073 //*************************************************************************
2074 BOOLEAN
ReloadSymbols(void)
2082 bResult
= LoadSymbolsFromConfig(TRUE
);
2089 //*************************************************************************
2092 //*************************************************************************
2093 void UnloadSymbols()
2099 if(ulNumSymbolsLoaded
)
2101 for(i
=0;i
<ulNumSymbolsLoaded
;i
++)
2103 DPRINT((0,"freeing [%u] %x\n",i
,apSymbols
[i
]));
2104 PICE_free(apSymbols
[i
]);
2105 apSymbols
[i
] = NULL
;
2107 ulNumSymbolsLoaded
= 0;
2112 //*************************************************************************
2113 // LoadSymbolsFromConfig()
2115 //*************************************************************************
2116 BOOLEAN
LoadSymbolsFromConfig(BOOLEAN bIgnoreBootParams
)
2119 LPSTR pConfig
,pConfigEnd
,pTemp
;
2122 BOOLEAN bResult
= FALSE
;
2126 hf
= PICE_open(L
"\\SystemRoot\\symbols\\pice.cfg",OF_READ
);
2129 //mm_segment_t oldfs;
2132 DPRINT((0,"hf = %x\n",hf
));
2135 DPRINT((0,"file len = %d\n",len
));
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);
2143 if(len
== PICE_read(hf
,(PVOID
)pConfig
,len
))
2147 pConfigEnd
= pConfig
+ len
;
2149 while(pConfig
<pConfigEnd
)
2151 // skip leading spaces
2152 while(*pConfig
==' ' && pConfig
<pConfigEnd
)
2154 // get ptr to temporary
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
2161 // skip any line ends
2162 while((*pConfig
==0x0a || *pConfig
==0x0d) && pConfig
<pConfigEnd
)
2165 // finally try to load the symbols
2166 if(PICE_strlen(temp
))
2168 PICE_SYMBOLFILE_HEADER
*pSymbols
;
2173 if(!bIgnoreBootParams
)
2175 if(!PICE_strlen(szBootParams
))
2177 PICE_strcpy(szBootParams
,temp
+1);
2178 DPRINT((0,"pICE: boot params = %s\n",szBootParams
));
2182 DPRINT((0,"pICE: boot params already exist! ignoring...\n",szBootParams
));
2187 else if(*temp
== '+')
2189 if(PICE_strlen(temp
)>1)
2191 if(PICE_strcmpi(temp
,"+vga")==0)
2193 eTerminalMode
= TERMINAL_MODE_VGA_TEXT
;
2194 DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_VGA_TEXT\n"));
2196 else if(PICE_strcmpi(temp
,"+hercules")==0)
2198 eTerminalMode
= TERMINAL_MODE_HERCULES_GRAPHICS
;
2199 DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_HERCULES_GRAPHICS\n"));
2201 else if(PICE_strcmpi(temp
,"+serial")==0)
2203 eTerminalMode
= TERMINAL_MODE_SERIAL
;
2204 DPRINT((0,"pICE: eTerminalMode = TERMINAL_MODE_SERIAL\n"));
2209 DPRINT((0,"pICE: found option, but no value\n"));
2213 else if(*temp
== '#')
2215 DPRINT((0,"comment out\n"));
2217 // symbol file name/path
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
));
2225 PICE_SYMBOLFILE_SOURCE
* pSrc
;
2228 pSrc
= (PICE_SYMBOLFILE_SOURCE
*)((ULONG
)pSymbols
+ pSymbols
->ulOffsetToSrcFiles
);
2229 pCurrentSymbols
= pSymbols
;
2230 p
= strrchr(pSrc
->filename
,'\\');
2233 PICE_strcpy(szCurrentFile
,p
+1);
2237 PICE_strcpy(szCurrentFile
,pSrc
->filename
);
2244 DPRINT((0,"invalid line [%u] in config!\n",line
));
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"));
2271 //*************************************************************************
2272 // EVALUATION OF EXPRESSIONS
2273 //*************************************************************************
2275 //*************************************************************************
2278 //*************************************************************************
2279 void SkipSpaces(void)
2281 while(pExpression
[ulIndex
]==' ')
2285 //*************************************************************************
2286 // FindGlobalStabSymbol()
2288 //*************************************************************************
2289 BOOLEAN
FindGlobalStabSymbol(LPSTR pExpression
,PULONG pValue
,PULONG pulTypeNumber
,PULONG pulFileNumber
)
2295 int nOffset
=0,nNextOffset
=0,nLen
,strLen
;
2296 PICE_SYMBOLFILE_HEADER
* pSymbols
;
2298 static char SymbolName
[1024];
2299 static char szCurrentPath
[256];
2300 ULONG ulCurrentFileNumber
=0;
2301 LPSTR pTypeDefIncluded
;
2304 // must have a current module
2307 // in case we query for the kernel we need to use the fake kernel module
2308 addr
= (ULONG
)pCurrentMod
->BaseAddress
;
2310 // find the symbols for the module
2311 pSymbols
= FindModuleSymbols(addr
);
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
2322 for(i
=0;i
<(nStabLen
/sizeof(STAB_ENTRY
));i
++)
2324 pName
= &pStr
[pStab
->n_strx
+ nOffset
];
2326 switch(pStab
->n_type
)
2328 // an N_UNDF symbol marks a change of string table offset
2330 nOffset
+= nNextOffset
;
2331 nNextOffset
= pStab
->n_value
;
2333 // a source file symbol
2335 if((strLen
= PICE_strlen(pName
)))
2337 if(pName
[strLen
-1]!='/')
2339 ulCurrentFileNumber
++;
2340 if(PICE_strlen(szCurrentPath
))
2342 PICE_strcat(szCurrentPath
,pName
);
2343 DPRINT((0,"changing source file %s\n",szCurrentPath
));
2347 DPRINT((0,"changing source file %s\n",pName
));
2351 PICE_strcpy(szCurrentPath
,pName
);
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)
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
);
2377 DPRINT((0,"value = %x\n",*pValue
));
2378 *pulFileNumber
= ulCurrentFileNumber
;
2379 DPRINT((0,"file = %x\n",ulCurrentFileNumber
));
2380 if((pTypeDefIncluded
= PICE_strchr(pName
,'=')) )
2382 DPRINT((0,"symbol includes type definition (%s)\n",pTypeDefIncluded
));
2395 //*************************************************************************
2398 //*************************************************************************
2399 void ExtractToken(LPSTR pStringToken
)
2401 while(PICE_isalpha(pExpression
[ulIndex
]) || PICE_isdigit(pExpression
[ulIndex
]) || pExpression
[ulIndex
]=='_')
2403 *pStringToken
++=pExpression
[ulIndex
++];
2408 //*************************************************************************
2409 // ExtractTypeName()
2411 //*************************************************************************
2412 LPSTR
ExtractTypeName(LPSTR p
)
2414 static char temp
[1024];
2417 DPRINT((1,"ExtractTypeName(%s)\n",p
));
2419 for(i
=0;IsAddressValid((ULONG
)p
) && *p
!=0 && *p
!=':';i
++,p
++)
2422 if(!IsAddressValid((ULONG
)p
) )
2424 DPRINT((1,"hit invalid page %x!\n",(ULONG
)p
));
2432 //*************************************************************************
2435 //*************************************************************************
2436 LONG
ExtractNumber(LPSTR p
)
2438 LONG lMinus
= 1,lBase
;
2441 DPRINT((0,"ExtractNumber(): %s\n",p
));
2443 if(!IsAddressValid((ULONG
)p
) )
2445 DPRINT((1,"ExtractNumber(): [1] invalid page %x hit!\n",p
));
2455 if(!IsAddressValid((ULONG
)p
) )
2457 DPRINT((1,"ExtractNumber(): [2] invalid page %x hit!\n",p
));
2461 if(*p
!= '0') // non-octal -> decimal number
2466 if(!IsAddressValid((ULONG
)p
) )
2468 DPRINT((1,"ExtractNumber(): [3] invalid page %x hit!\n",p
));
2472 while(PICE_isdigit(*p
))
2477 if(!IsAddressValid((ULONG
)p
) )
2479 DPRINT((1,"ExtractNumber(): [4] invalid page %x hit!\n",p
));
2484 return (lNumber
*lMinus
);
2487 //*************************************************************************
2490 //*************************************************************************
2491 BOOLEAN
ExtractArray(PVRET pvr
,LPSTR p
)
2493 ULONG index_typenumber
,type_number
;
2494 ULONG lower_bound
,upper_bound
;
2497 DPRINT((1,"ExtractArray(%s)\n",p
));
2499 // index-type index-type-number;lower;upper;element-type-number
2500 pvr
->bArrayType
= TRUE
;
2502 index_typenumber
= ExtractTypeNumber(p
);
2503 p
= PICE_strchr(p
,';');
2507 lower_bound
= ExtractNumber(p
);
2508 p
= PICE_strchr(p
,';');
2513 upper_bound
= ExtractNumber(p
);
2514 p
= PICE_strchr(p
,';');
2519 type_number
= ExtractTypeNumber(p
);
2521 DPRINT((1,"ExtractArray(): %x %x %x %x\n",index_typenumber
,lower_bound
,upper_bound
,type_number
));
2523 pTypeDef
= FindTypeDefinition(pvr
->pSymbols
,type_number
,pvr
->file
);
2526 PICE_strcpy(pvr
->type_name
,ExtractTypeName(pTypeDef
));
2527 pvr
->type
= type_number
;
2536 //*************************************************************************
2537 // ExtractStructMembers()
2539 //*************************************************************************
2540 PVRET
ExtractStructMembers(PVRET pvr
,LPSTR p
)
2543 static char member_name
[128];
2544 LONG bit_offset
,bit_size
,type_number
,byte_size
;
2546 LPSTR pTypeDef
,pEqual
;
2548 DPRINT((1,"ExtractStructMembers(): %s\n",p
));
2550 PICE_memset(&vr
,0,sizeof(vr
));
2552 // name:type-number,bit-offset,bit-size
2553 len
=StrLenUpToWhiteChar(p
,":");
2556 // extract member name
2557 PICE_strncpy(member_name
,p
,len
);
2559 DPRINT((1,"ExtractStructMembers(): member_name = %s\n",member_name
));
2561 // go to char following ':'
2563 if(IsAddressValid((ULONG
)p
) )
2565 type_number
= ExtractTypeNumber(p
);
2566 DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number
));
2568 vr
.type
= type_number
;
2570 pEqual
= PICE_strchr(p
,')');
2571 // see if it includes type def
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
,';');
2588 type_number
= ExtractTypeNumber(p
);
2589 vr
.father_type
= type_number
;
2593 DPRINT((1,"ExtractStructMembers(): member is ptr\n"));
2595 type_number
= ExtractTypeNumber(p
);
2596 DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number
));
2597 vr
.father_type
= type_number
;
2601 DPRINT((1,"ExtractStructMembers(): member is union\n"));
2602 while(*p
!=';' && *(p
+1)!=';' && *p
!=0)p
++;
2607 p
= PICE_strchr(p
,',');
2611 bit_offset
= ExtractNumber(p
);
2612 DPRINT((1,"ExtractStructMembers(): bit_offset = %x\n",bit_offset
));
2613 p
= PICE_strchr(p
,',');
2618 bit_size
= ExtractNumber(p
);
2619 DPRINT((1,"ExtractStructMembers(): bit_size = %x\n",bit_size
));
2621 vr
.address
= pvr
->value
+ bit_offset
/8;
2622 vr
.file
= pvr
->file
;
2624 PICE_strcpy(vr
.name
,member_name
);
2625 byte_size
= (bit_size
+1)/8;
2628 pvr
->address
= pvr
->value
;
2629 if(IsRangeValid(vr
.address
,byte_size
))
2634 vr
.value
= *(PUCHAR
)vr
.address
;
2637 vr
.value
= *(PUSHORT
)vr
.address
;
2640 vr
.value
= *(PULONG
)vr
.address
;
2645 DPRINT((1,"ExtractStructMembers(): member %s type %x bit_offset %x bit_size%x\n",member_name
,type_number
,bit_offset
,bit_size
));
2647 pTypeDef
= FindTypeDefinition(pvr
->pSymbols
,type_number
,pvr
->file
);
2650 DPRINT((1,"ExtractStructMembers(): pTypedef= %s\n",pTypeDef
));
2651 PICE_strcpy(vr
.type_name
,ExtractTypeName(pTypeDef
));
2652 pTypeDef
= PICE_strchr(pTypeDef
,':');
2656 type_number
= ExtractTypeNumber(pTypeDef
);
2657 DPRINT((1,"ExtractStructMembers(): type_number = %x\n",type_number
));
2658 vr
.father_type
= type_number
;
2669 //*************************************************************************
2672 //*************************************************************************
2673 BOOLEAN
EvaluateSymbol(PVRET pvr
,LPSTR pToken
)
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];
2681 DPRINT((1,"EvaluateSymbol(%s)\n",pToken
));
2683 if(FindGlobalStabSymbol(pToken
,&pvr
->value
,&pvr
->type
,&pvr
->file
))
2685 DPRINT((1,"EvaluateSymbol(%s) pvr->value = %x pvr->type = %x\n",pToken
,pvr
->value
,pvr
->type
));
2688 if(!(pTypeDef
= FindTypeDefinition(pvr
->pSymbols
,pvr
->type
,pvr
->file
)))
2690 PICE_strcpy(type_def
,pTypeDef
);
2692 pTypeDef
= type_def
;
2694 pTypeName
= ExtractTypeName(pTypeDef
);
2696 DPRINT((1,"%s %s\n",pTypeName
,pToken
));
2698 PICE_strcpy(pvr
->type_name
,pTypeName
);
2700 pTypeBase
= PICE_strchr(pTypeDef
,'=');
2709 case '(': // type reference
2710 ulType
= ExtractTypeNumber(pTypeBase
);
2711 DPRINT((1,"%x is a type reference to %x\n",pvr
->type
,ulType
));
2714 case 'r': // subrange
2716 ulType
= ExtractTypeNumber(pTypeBase
);
2717 DPRINT((1,"%x is sub range of %x\n",pvr
->type
,ulType
));
2718 if(pvr
->type
== ulType
)
2720 DPRINT((1,"%x is a self reference\n",pvr
->type
));
2721 pSemiColon
= PICE_strchr(pTypeBase
,';');
2723 lLowerRange
= ExtractNumber(pSemiColon
);
2724 pSemiColon
= PICE_strchr(pSemiColon
,';');
2726 lUpperRange
= ExtractNumber(pSemiColon
);
2727 lDelta
= lUpperRange
-lLowerRange
;
2728 DPRINT((1,"bounds %x-%x range %x\n",lLowerRange
,lUpperRange
,lDelta
));
2735 ulBytes
= (ulBits
+1)/8;
2738 DPRINT((1,"# of bytes = %x\n",ulBytes
));
2739 pvr
->address
= pvr
->value
;
2740 if(IsRangeValid(pvr
->value
,ulBytes
))
2745 pvr
->value
= *(PUCHAR
)pvr
->value
;
2748 pvr
->value
= *(PUSHORT
)pvr
->value
;
2751 pvr
->value
= *(PULONG
)pvr
->value
;
2760 case 'a': // array type
2761 DPRINT((1,"%x array\n",pvr
->type
));
2763 if(!ExtractArray(pvr
,pTypeBase
))
2769 case '*': // ptr type
2770 DPRINT((1,"%x is ptr to\n",pvr
->type
));
2771 bDone
= TRUE
; // meanwhile
2773 case 's': // struct type [name:T(#,#)=s#membername1:(#,#),#,#;membername1:(#,#),#,#;;]
2777 // extract the the struct size
2778 lLowerRange
= ExtractNumber(pTypeBase
);
2779 DPRINT((1,"%x struct size = %x\n",pvr
->type
,lLowerRange
));
2781 // skip over the digits
2782 while(PICE_isdigit(*pTypeBase
))
2785 // the structs address is is value
2786 pvr
->address
= pvr
->value
;
2787 pvr
->bStructType
= TRUE
;
2789 // decode the struct members. pStructMembers now points to first member name
2790 pStructMembers
= pTypeBase
;
2792 while(pStructMembers
&& *pStructMembers
&& *pStructMembers
!=';' && ulNumStructMembers
<DIM(vrStructMembers
))
2794 DPRINT((1,"EvaluateSymbol(): member #%u\n",ulNumStructMembers
));
2795 // put this into our array
2796 vrStructMembers
[ulNumStructMembers
] = *ExtractStructMembers(pvr
,pStructMembers
);
2798 if(!PICE_strlen(vrStructMembers
[ulNumStructMembers
].type_name
))
2801 PVRET pvrThis
= &vrStructMembers
[ulNumStructMembers
];
2803 DPRINT((1,"EvaluateSymbol(): no type name\n"));
2804 for(i
=0;i
<ulNumStructMembers
;i
++)
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
)
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
;
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
));
2830 ulNumStructMembers
++;
2833 pStructMembers
= PICE_strchr(pStructMembers
,';');
2834 pStructMembers
= PICE_strchr(pStructMembers
,':');
2837 DPRINT((1,"EvaluateSymbol(): ptr is now %s\n",pStructMembers
));
2838 // go back to where member name starts
2839 while(*pStructMembers
!=';')
2841 // if ';' present, go to next char
2847 bDone
= TRUE
; // meanwhile
2849 case 'u': // union type
2850 DPRINT((1,"%x union\n",pvr
->type
));
2851 bDone
= TRUE
; // meanwhile
2853 case 'e': // enum type
2854 DPRINT((1,"%x enum\n",pvr
->type
));
2855 bDone
= TRUE
; // meanwhile
2858 DPRINT((1,"DEFAULT %x, base: %c\n",pvr
->type
, *pTypeBase
));
2859 pvr
->address
= pvr
->value
;
2860 if(IsRangeValid(pvr
->value
,ulBytes
))
2865 pvr
->value
= *(PUCHAR
)pvr
->value
;
2868 pvr
->value
= *(PUSHORT
)pvr
->value
;
2871 pvr
->value
= *(PULONG
)pvr
->value
;
2885 //*************************************************************************
2889 //*************************************************************************
2890 BOOLEAN
Symbol(PVRET pvr
)
2892 char SymbolToken
[128];
2894 ExtractToken(SymbolToken
);
2896 DPRINT((1,"SymbolToken = %s\n",SymbolToken
));
2898 return EvaluateSymbol(pvr
,SymbolToken
);
2901 //*************************************************************************
2904 // Expression := Symbol | Symbol->Symbol
2905 //*************************************************************************
2906 BOOLEAN
Expression(PVRET pvr
)
2914 //*************************************************************************
2917 //*************************************************************************
2918 void Evaluate(PICE_SYMBOLFILE_HEADER
* pSymbols
,LPSTR p
)
2922 PICE_memset(&vr
,0,sizeof(vr
));
2923 vr
.pSymbols
= pSymbols
;
2927 ulNumStructMembers
=0;
2930 DPRINT((1,"\nOK!\n"));
2931 DPRINT((1,"value = %x type = %x\n",vr
.value
,vr
.type
));
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
++)
2938 if(vrStructMembers
[i
].bArrayType
)
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);
2947 else if(vrStructMembers
[i
].bPtrType
)
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
);
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
);
2967 Print(OUTPUT_WINDOW
,tempSym
);
2970 else if(vr
.bArrayType
)
2972 Print(OUTPUT_WINDOW
,"array\n");
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
);
2982 DPRINT((1,"\nERROR: code %x\n",vr
.error
));