home *** CD-ROM | disk | FTP | other *** search
- /*++
-
-
- Copyright 1996 - 1997 Microsoft Corporation
-
- Module Name:
-
- cv.c
-
- Abstract:
-
- This module handles the conversion activities requires for converting
- COFF debug data to CODEVIEW debug data.
-
- Author:
-
- Wesley A. Witt (wesw) 19-April-1993
-
- Environment:
-
- Win32, User Mode
-
- --*/
-
- #include <windows.h>
- #include <imagehlp.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-
- #include "cv.h"
- #define _SYMCVT_SOURCE_
- #include "symcvt.h"
- #include "cvcommon.h"
-
- typedef struct tagOFFSETSORT {
- DWORD dwOffset; // offset for the symbol
- DWORD dwSection; // section number of the symbol
- DATASYM32 *dataSym; // pointer to the symbol info
- } OFFSETSORT;
-
-
- #define n_name N.ShortName
- #define n_zeroes N.Name.Short
- #define n_nptr N.LongName[1]
- #define n_offset N.Name.Long
-
- static LPSTR GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s );
- DWORD CreateModulesFromCoff( PPOINTERS p );
- DWORD CreatePublicsFromCoff( PPOINTERS p );
- DWORD CreateSegMapFromCoff( PPOINTERS p );
- DWORD CreateSrcLinenumbers( PPOINTERS p );
-
-
-
- LONG
- GuardPageFilterFunction(
- DWORD ec,
- LPEXCEPTION_POINTERS lpep
- )
-
- /*++
-
- Routine Description:
-
- This function catches all exceptions from the convertcofftocv function
- and all that it calls. The purpose of this function is allocate memory
- when it is necessary. This happens because the cofftocv conversion cannot
- estimate the memory requirements before the conversion takes place. To
- handle this properly space in the virtual address space is reserved, the
- reservation amount is 10 times the image size. The first page is commited
- and then the conversion is started. When an access violation occurs and the
- page that is trying to be access has a protection of noaccess then the
- page is committed. Any other exception is not handled.
-
- Arguments:
-
- ec - the ecxeption code (should be EXCEPTION_ACCESS_VIOLATION)
- lpep - pointer to the exception record and context record
-
-
- Return Value:
-
- EXCEPTION_CONTINUE_EXECUTION - access violation handled
- EXCEPTION_EXECUTE_HANDLER - unknown exception and is not handled
-
- --*/
-
- {
- LPVOID vaddr;
- SYSTEM_INFO si;
- MEMORY_BASIC_INFORMATION mbi;
-
-
- if (ec == EXCEPTION_ACCESS_VIOLATION) {
- vaddr = (LPVOID)lpep->ExceptionRecord->ExceptionInformation[1];
- VirtualQuery( vaddr, &mbi, sizeof(mbi) );
- if (mbi.AllocationProtect == PAGE_NOACCESS) {
- GetSystemInfo( &si );
- VirtualAlloc( vaddr, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
- return EXCEPTION_CONTINUE_EXECUTION;
- }
- }
-
- // return EXCEPTION_CONTINUE_SEARCH;
- return EXCEPTION_EXECUTE_HANDLER;
- }
-
-
- BOOL
- ConvertCoffToCv( PPOINTERS p )
-
- /*++
-
- Routine Description:
-
- This is the control function for the conversion of COFF to CODEVIEW
- debug data. It calls individual functions for the conversion of
- specific types of debug data.
-
-
- Arguments:
-
- p - pointer to a POINTERS structure
-
-
- Return Value:
-
- TRUE - conversion succeded
- FALSE - conversion failed
-
- --*/
-
- {
- SYSTEM_INFO si;
- DWORD cbsize;
- BOOL rval = TRUE;
-
-
- GetSystemInfo( &si );
- cbsize = max( p->iptrs.fsize * 10, si.dwPageSize * 10 );
-
- //
- // reserve all necessary pages
- //
- p->pCvCurr = p->pCvStart.ptr = VirtualAlloc( NULL, cbsize, MEM_RESERVE, PAGE_NOACCESS );
-
- //
- // commit the first pages
- //
- VirtualAlloc( p->pCvCurr, min( cbsize, 5 * si.dwPageSize), MEM_COMMIT, PAGE_READWRITE );
-
-
- try {
-
- CreateSignature( p );
- CreateModulesFromCoff( p );
- CreatePublicsFromCoff( p );
- CreateSymbolHashTable( p );
- CreateAddressSortTable( p );
- CreateSegMapFromCoff( p );
- // CreateSrcLinenumbers( p );
- CreateDirectories( p );
-
- } except ( GuardPageFilterFunction( GetExceptionCode(), GetExceptionInformation() )) {
-
- VirtualFree( p->pCvStart.ptr, cbsize, MEM_DECOMMIT );
- p->pCvStart.ptr = NULL;
- rval = FALSE;
-
- }
-
- if (rval) {
- p->pCvCurr = malloc( p->pCvStart.size );
- CopyMemory( p->pCvCurr, p->pCvStart.ptr, p->pCvStart.size );
- VirtualFree( p->pCvStart.ptr, cbsize, MEM_DECOMMIT );
- p->pCvStart.ptr = p->pCvCurr;
- }
-
- return rval;
- }
-
-
- DWORD
- CreateModulesFromCoff( PPOINTERS p )
-
- /*++
-
- Routine Description:
-
- Creates the individual CV module records. There is one CV module
- record for each .FILE record in the COFF debug data. This is true
- even if the COFF size is zero.
-
-
- Arguments:
-
- p - pointer to a POINTERS structure
-
-
- Return Value:
-
- The number of modules that were created.
-
- --*/
-
- {
- int i,j;
- DWORD dwOff;
- DWORD numaux;
- DWORD nummods = 0;
- char szSymName[256];
- PIMAGE_SYMBOL Symbol;
- PIMAGE_AUX_SYMBOL AuxSymbol;
- OMFModule *m = NULL;
- int cSeg = 0;
- char * pb;
- BOOLEAN rgfCode[500];
-
-
- memset(rgfCode, 2, sizeof(rgfCode));
-
- for (i=0,j=0, Symbol=p->iptrs.AllSymbols;
- i<(int)p->iptrs.numberOfSymbols;
- i+=numaux+1,Symbol+=numaux+1) {
-
- numaux = Symbol->NumberOfAuxSymbols;
- if (Symbol->StorageClass == IMAGE_SYM_CLASS_FILE) {
- j++;
- }
-
- }
-
- p->pMi = (LPMODULEINFO) malloc( sizeof(MODULEINFO) * (j + 1) );
- ZeroMemory( p->pMi, sizeof(MODULEINFO) * (j + 1) );
-
-
- if (!j) {
- //
- // Handle the situation where there are not any .file records in the
- // COFF symbol table. This can happen for ROM images. If this happens
- // then we will fabricate a bogus module.
- //
- m = (OMFModule *) p->pCvCurr;
- m->ovlNumber = 0;
- m->iLib = 0;
- m->Style[0] = 'C';
- m->Style[1] = 'V';
-
- for (i=0,j=0, dwOff=0; i<p->iptrs.numberOfSections; i++) {
- if (p->iptrs.sectionHdrs[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) {
- m->SegInfo[j].Seg = i + 1;
- m->SegInfo[j].cbSeg = p->iptrs.sectionHdrs[i].SizeOfRawData;
- m->SegInfo[j++].Off = dwOff;
- }
- dwOff += p->iptrs.sectionHdrs[i].SizeOfRawData;
- }
-
- m->cSeg = j;
-
- strcpy(szSymName,"foo.c");
- pb = (char *) &m->SegInfo[j];
- *pb = strlen(szSymName);
- memcpy(pb+1, szSymName, *pb);
-
- p->pMi[0].name = strdup(szSymName);
- p->pMi[0].iMod = 1;
- p->pMi[0].cb = 0;
- p->pMi[0].SrcModule = 0;
-
- m = NextMod(m);
- p->modcnt = 1;
- UpdatePtrs( p, &p->pCvModules, (LPVOID)m, 1 );
-
- return 1;
- }
-
-
- for (i=0, Symbol = p->iptrs.AllSymbols;
- i < (int) p->iptrs.numberOfSymbols;
- i += numaux + 1, Symbol += numaux + 1) {
-
- //
- // Get the number of aux symbol records for this symbol
- //
- numaux = Symbol->NumberOfAuxSymbols;
- AuxSymbol = (PIMAGE_AUX_SYMBOL) (Symbol+1);
-
- if ((i == 0) && ((Symbol+numaux+1)->StorageClass != IMAGE_SYM_CLASS_FILE)) {
- //
- // we have a situation where the first '.file' record
- // is missing. currently this only happens with the
- // claxp compiler on alpha.
- //
- m = (OMFModule *) p->pCvCurr;
- cSeg = 0;
- m->ovlNumber = 0;
- m->iLib = 0;
- m->Style[0] = 'C';
- m->Style[1] = 'V';
- strcpy( szSymName, "fake.c" );
- } else
-
- //
- // If this is a FILE record -- then we need to create a
- // module item to correspond to this file record.
- //
-
- if (Symbol->StorageClass == IMAGE_SYM_CLASS_FILE) {
- if (m == NULL) {
- m = (OMFModule *) p->pCvCurr;
- } else {
- //
- // Clean up the last item, if we saw any
- // section records then drop them in here
- //
-
- if (cSeg > 0) {
- m->cSeg = cSeg;
- pb = (char *) &m->SegInfo[cSeg];
- *pb = strlen(szSymName);
- memcpy(pb+1, szSymName, *pb);
-
- p->pMi[nummods].name = strdup(szSymName);
- p->pMi[nummods].iMod = nummods + 1;
- p->pMi[nummods].cb = 0;
- p->pMi[nummods].SrcModule = 0;
-
- m = NextMod(m);
- nummods++;
- }
- }
-
- cSeg = 0;
- m->ovlNumber = 0;
- m->iLib = 0;
- m->Style[0] = 'C';
- m->Style[1] = 'V';
-
- /*
- * Save off the file name to use when we have finished
- * processing this module
- */
-
- memcpy(szSymName, (char *)AuxSymbol, numaux*sizeof(IMAGE_AUX_SYMBOL));
- szSymName[numaux*sizeof(IMAGE_AUX_SYMBOL)] = 0;
-
- }
- /*
- * We have found a "SECTION" record. Add the info to the
- * module record
- */
- else
- if ((Symbol->SectionNumber & 0xffff) > 0xfff0) {
- continue;
- } else
- if (Symbol->SectionNumber > sizeof(rgfCode)/sizeof(rgfCode[0])) {
- return 0;
- } else
- if ((m != NULL) &&
- (rgfCode[Symbol->SectionNumber] != 0) &&
- (Symbol->StorageClass == IMAGE_SYM_CLASS_STATIC) &&
- ((*Symbol->n_name == '.') ||
- (Symbol->Type == IMAGE_SYM_TYPE_NULL)) &&
- (Symbol->NumberOfAuxSymbols == 1) &&
- (AuxSymbol->Section.Length != 0)) {
-
- if (rgfCode[Symbol->SectionNumber] == 2) {
- if ((p->iptrs.sectionHdrs[Symbol->SectionNumber - 1].
- Characteristics & IMAGE_SCN_CNT_CODE) == 0) {
- rgfCode[Symbol->SectionNumber] = 0;
- continue;
- }
- rgfCode[Symbol->SectionNumber] = 1;
- }
-
- m->SegInfo[cSeg].Seg = Symbol->SectionNumber;
- m->SegInfo[cSeg].cbSeg = AuxSymbol->Section.Length;
- m->SegInfo[cSeg].Off = Symbol->Value -
- p->iptrs.sectionHdrs[Symbol->SectionNumber-1].
- VirtualAddress;
- cSeg += 1;
- }
- }
-
- /*
- * Wrap up the last possible open module record
- */
-
- if (m != NULL) {
- if (cSeg > 0) {
- m->cSeg = cSeg;
- pb = (char *) &m->SegInfo[cSeg];
- *pb = strlen(szSymName);
- memcpy(pb+1, szSymName, *pb);
-
- p->pMi[nummods].name = strdup(szSymName);
- p->pMi[nummods].iMod = nummods + 1;
- p->pMi[nummods].cb = 0;
- p->pMi[nummods].SrcModule = 0;
-
- m = NextMod(m);
- nummods++;
- }
- }
-
-
- p->modcnt = nummods;
- UpdatePtrs( p, &p->pCvModules, (LPVOID)m, nummods );
-
- return nummods;
- }
-
-
- DWORD
- CreatePublicsFromCoff( PPOINTERS p )
-
- /*++
-
- Routine Description:
-
- Creates the individual CV public symbol records. There is one CV
- public record created for each COFF symbol that is marked as EXTERNAL
- and has a section number greater than zero. The resulting CV publics
- are sorted by section and offset.
-
-
- Arguments:
-
- p - pointer to a POINTERS structure
-
-
- Return Value:
-
- The number of publics created.
-
- --*/
-
- {
- int i;
- DWORD numaux;
- DWORD numsyms = 0;
- char szSymName[256];
- PIMAGE_SYMBOL Symbol;
- OMFSymHash *omfSymHash;
- DATASYM32 *dataSym;
- DATASYM32 *dataSym2;
-
- omfSymHash = (OMFSymHash *) p->pCvCurr;
- dataSym = (DATASYM32 *) (PUCHAR)((DWORD)omfSymHash + sizeof(OMFSymHash));
-
- for (i= 0, Symbol = p->iptrs.AllSymbols;
- i < p->iptrs.numberOfSymbols;
- i += numaux + 1, Symbol += numaux + 1) {
-
- if ((Symbol->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) &&
- (Symbol->SectionNumber > 0)) {
-
- if (GetSymName( Symbol, p->iptrs.stringTable, szSymName )) {
- dataSym->rectyp = S_PUB32;
- dataSym->seg = Symbol->SectionNumber;
- dataSym->off = Symbol->Value -
- p->iptrs.sectionHdrs[Symbol->SectionNumber-1].VirtualAddress;
- dataSym->typind = 0;
- dataSym->name[0] = strlen( szSymName );
- strcpy( &dataSym->name[1], szSymName );
- dataSym2 = NextSym32( dataSym );
- dataSym->reclen = (USHORT) ((DWORD)dataSym2 - (DWORD)dataSym) - 2;
- dataSym = dataSym2;
- numsyms += 1;
- }
- }
- numaux = Symbol->NumberOfAuxSymbols;
- }
-
- UpdatePtrs( p, &p->pCvPublics, (LPVOID)dataSym, numsyms );
-
- omfSymHash->cbSymbol = p->pCvPublics.size - sizeof(OMFSymHash);
- omfSymHash->symhash = 0;
- omfSymHash->addrhash = 0;
- omfSymHash->cbHSym = 0;
- omfSymHash->cbHAddr = 0;
-
- return numsyms;
- } /* CreatePublisFromCoff() */
-
-
- DWORD
- CreateSrcLinenumbers(
- PPOINTERS p
- )
-
- /*++
-
- Routine Description:
-
- Creates the individual CV soure line number records.
-
-
- Arguments:
-
- p - pointer to a POINTERS structure
-
-
- Return Value:
-
- The number of publics created.
-
- --*/
-
- {
- typedef struct _SEGINFO {
- DWORD start;
- DWORD end;
- DWORD cbLines;
- DWORD ptrLines;
- DWORD va;
- DWORD num;
- BOOL used;
- } SEGINFO, *LPSEGINFO;
-
- typedef struct _SRCINFO {
- LPSEGINFO seg;
- DWORD numSeg;
- DWORD cbSeg;
- CHAR name[MAX_PATH+1];
- } SRCINFO, *LPSRCINFO;
-
- typedef struct _SECTINFO {
- DWORD va;
- DWORD size;
- DWORD ptrLines;
- DWORD numLines;
- } SECTINFO, *LPSECTINFO;
-
-
- DWORD i;
- DWORD j;
- DWORD k;
- DWORD l;
- DWORD actual;
- DWORD sidx;
- DWORD NumSrcFiles;
- DWORD SrcFileCnt;
- DWORD numaux;
- PIMAGE_SYMBOL Symbol;
- PIMAGE_AUX_SYMBOL AuxSymbol;
- BOOL first = TRUE;
- OMFSourceModule *SrcModule;
- OMFSourceFile *SrcFile;
- OMFSourceLine *SrcLine;
- LPBYTE lpb;
- LPDWORD lpdw;
- PUSHORT lps;
- PUCHAR lpc;
- PIMAGE_LINENUMBER pil, pilSave;
- LPSRCINFO si;
- LPSECTINFO sections;
-
-
- //
- // setup the section info structure
- //
- sections = (LPSECTINFO) malloc( sizeof(SECTINFO) * p->iptrs.numberOfSections );
- for (i=0; i<(DWORD)p->iptrs.numberOfSections; i++) {
- sections[i].va = p->iptrs.sectionHdrs[i].VirtualAddress;
- sections[i].size = p->iptrs.sectionHdrs[i].SizeOfRawData;
- sections[i].ptrLines = p->iptrs.sectionHdrs[i].PointerToLinenumbers;
- sections[i].numLines = p->iptrs.sectionHdrs[i].NumberOfLinenumbers;
- }
-
- //
- // count the number of source files that contibute linenumbers
- //
- SrcFileCnt = 100;
- si = (LPSRCINFO) malloc( sizeof(SRCINFO) * SrcFileCnt );
- ZeroMemory( si, sizeof(SRCINFO) * SrcFileCnt );
- for (i=0, j=0, Symbol=p->iptrs.AllSymbols, NumSrcFiles=0;
- i<(DWORD)p->iptrs.numberOfSymbols;
- i+=(numaux+1), Symbol+=(numaux + 1)) {
-
- numaux = Symbol->NumberOfAuxSymbols;
- AuxSymbol = (PIMAGE_AUX_SYMBOL) (Symbol+1);
-
- if (Symbol->StorageClass == IMAGE_SYM_CLASS_FILE) {
-
- if (!first) {
- si[NumSrcFiles].cbSeg = j;
- NumSrcFiles++;
- if (NumSrcFiles == SrcFileCnt) {
- SrcFileCnt += 100;
- si = (LPSRCINFO) realloc( si, sizeof(SRCINFO) * SrcFileCnt );
- }
- }
-
- memcpy(si[NumSrcFiles].name, (char *)AuxSymbol, numaux*sizeof(IMAGE_AUX_SYMBOL));
- si[NumSrcFiles].name[numaux*sizeof(IMAGE_AUX_SYMBOL)] = 0;
- si[NumSrcFiles].numSeg = 100;
- si[NumSrcFiles].seg = (LPSEGINFO) malloc( sizeof(SEGINFO) * si[NumSrcFiles].numSeg );
- ZeroMemory( si[NumSrcFiles].seg, sizeof(SEGINFO) * si[NumSrcFiles].numSeg );
- first = FALSE;
- j = 0;
-
- }
-
- //
- // we do not want to look for segment information until we
- // have found a valid source file
- //
- if (first) {
- continue;
- }
-
- //
- // check the symbol to see if it is a segment record
- //
- if (numaux && Symbol->StorageClass == IMAGE_SYM_CLASS_STATIC &&
- (*Symbol->n_name == '.' ||
- ((Symbol->Type & 0xf) == IMAGE_SYM_TYPE_NULL && AuxSymbol->Section.Length)) &&
- AuxSymbol->Section.NumberOfLinenumbers > 0) {
-
- //
- // find the section that this symbol belongs to
- //
- for (k=0; k<(DWORD)p->iptrs.numberOfSections; k++) {
- if (Symbol->Value >= sections[k].va &&
- Symbol->Value < sections[k].va + sections[k].size) {
-
- sidx = k;
- break;
-
- }
- }
-
- if (k != (DWORD)p->iptrs.numberOfSections &&
- p->iptrs.sectionHdrs[k].NumberOfLinenumbers) {
-
- pil = (PIMAGE_LINENUMBER) (p->iptrs.fptr + sections[sidx].ptrLines);
- k = 0;
-
- while( k < AuxSymbol->Section.NumberOfLinenumbers ) {
-
- //
- // count the linenumbers in this section or sub-section
- //
- for ( pilSave=pil,l=0;
- k<AuxSymbol->Section.NumberOfLinenumbers;
- k++,pilSave++,l++ ) {
-
- if ((k != (DWORD)AuxSymbol->Section.NumberOfLinenumbers-1) &&
- (pilSave->Linenumber > (pilSave+1)->Linenumber)) {
- pilSave++;
- l++;
- break;
- }
-
- }
-
- //
- // pil == beginning of the range
- // pilSave == end of the range
- //
-
- si[NumSrcFiles].seg[j].start =
- (pil->Type.VirtualAddress - sections[sidx].va);
-
- if (sections[sidx].numLines == l) {
- pilSave--;
- si[NumSrcFiles].seg[j].end =
- (pilSave->Type.VirtualAddress - sections[sidx].va) + 1;
- // (Symbol->Value - sections[sidx].va) + 1;
- } else {
- si[NumSrcFiles].seg[j].end =
- (pilSave->Type.VirtualAddress - sections[sidx].va) - 1;
- // (Symbol->Value - sections[sidx].va) - 1;
- }
-
- si[NumSrcFiles].seg[j].ptrLines = sections[sidx].ptrLines;
- si[NumSrcFiles].seg[j].cbLines = l;
- si[NumSrcFiles].seg[j].va = sections[sidx].va;
- si[NumSrcFiles].seg[j].num = sidx + 1;
- si[NumSrcFiles].seg[j].used = FALSE;
-
- sections[sidx].ptrLines += (l * sizeof(IMAGE_LINENUMBER));
- sections[sidx].numLines -= l;
-
- j++;
- if (j == si[NumSrcFiles].numSeg) {
- si[NumSrcFiles].numSeg += 100;
- si[NumSrcFiles].seg = (LPSEGINFO) realloc( si[NumSrcFiles].seg, sizeof(SEGINFO) * si[NumSrcFiles].numSeg );
- }
- k++;
- pil = pilSave;
- }
-
- }
-
- }
-
- }
-
- lpb = (LPBYTE) p->pCvCurr;
-
- //
- // if there is nothing to do then bail out
- //
- if (!NumSrcFiles) {
- UpdatePtrs( p, &p->pCvSrcModules, (LPVOID)lpb, 0 );
- return 0;
- }
-
- for (i=0,actual=0,l=0; i<NumSrcFiles; i++) {
-
- if (si[i].cbSeg == 0) {
- continue;
- }
-
- //
- // create the source module header
- //
- SrcModule = (OMFSourceModule*) lpb;
- SrcModule->cFile = 1;
- SrcModule->cSeg = (USHORT)si[i].cbSeg;
- SrcModule->baseSrcFile[0] = 0;
-
- //
- // write the start/end pairs
- //
- lpdw = (LPDWORD) ((LPBYTE)SrcModule + sizeof(OMFSourceModule));
- for (k=0; k<si[i].cbSeg; k++) {
- *lpdw++ = si[i].seg[k].start;
- *lpdw++ = si[i].seg[k].end;
- }
-
- //
- // write the segment numbers
- //
- lps = (PUSHORT) lpdw;
- for (k=0; k<si[i].cbSeg; k++) {
- *lps++ = (USHORT)si[i].seg[k].num;
- }
-
- //
- // align to a dword boundry
- //
- lps = (PUSHORT) ((LPBYTE)lps + align(lps));
-
- //
- // update the base pointer
- //
- SrcModule->baseSrcFile[0] = (DWORD) ((LPBYTE)lps - (LPBYTE)SrcModule);
-
- //
- // write the source file record
- //
- SrcFile = (OMFSourceFile*) lps;
- SrcFile->cSeg = (USHORT)si[i].cbSeg;
- SrcFile->reserved = 0;
-
- for (k=0; k<si[i].cbSeg; k++) {
- SrcFile->baseSrcLn[k] = 0;
- }
-
- //
- // write the start/end pairs
- //
- lpdw = (LPDWORD) ((LPBYTE)SrcFile + 4 + (4 * si[i].cbSeg));
- for (k=0; k<si[i].cbSeg; k++) {
- *lpdw++ = si[i].seg[k].start;
- *lpdw++ = si[i].seg[k].end;
- }
-
- //
- // write the source file name
- //
- lpc = (PUCHAR) lpdw;
- k = strlen(si[i].name);
- *lpc++ = (UCHAR) k;
- strcpy( lpc, si[i].name );
- lpb = lpc + k;
-
- //
- // find the module info struct
- //
- for (; l<p->modcnt; l++) {
- if (stricmp(p->pMi[l].name,si[i].name)==0) {
- break;
- }
- }
-
- p->pMi[l].SrcModule = (DWORD) SrcModule;
-
- //
- // align to a dword boundry
- //
- lpb = (LPBYTE) (lpb + align(lpb));
-
- //
- // create the line number pairs
- //
- for (k=0; k<si[i].cbSeg; k++) {
-
- //
- // find the first line number that applies to this segment
- //
- pil = (PIMAGE_LINENUMBER) (p->iptrs.fptr + si[i].seg[k].ptrLines);
-
- //
- // update the base pointer
- //
- SrcFile->baseSrcLn[k] = (DWORD) (lpb - (LPBYTE)SrcModule);
-
- //
- // write the line numbers
- //
- SrcLine = (OMFSourceLine*) lpb;
- SrcLine->Seg = (USHORT)si[i].seg[k].num;
- SrcLine->cLnOff = (USHORT) si[i].seg[k].cbLines;
- pilSave = pil;
- lpdw = (LPDWORD) (lpb + 4);
- for (j=0; j<SrcLine->cLnOff; j++) {
- *lpdw++ = pil->Type.VirtualAddress - si[i].seg[k].va;
- pil++;
- }
- lps = (PUSHORT) lpdw;
- pil = pilSave;
- for (j=0; j<SrcLine->cLnOff; j++) {
- *lps++ = pil->Linenumber;
- pil++;
- }
-
- //
- // align to a dword boundry
- //
- lps = (PUSHORT) ((LPBYTE)lps + align(lps));
-
- lpb = (LPBYTE) lps;
- }
-
- p->pMi[l].cb = (DWORD)lpb - (DWORD)SrcModule;
- actual++;
-
- }
-
- UpdatePtrs( p, &p->pCvSrcModules, (LPVOID)lpb, actual );
-
- //
- // cleanup all allocated memory
- //
-
- free( sections );
-
- for (i=0; i<SrcFileCnt; i++) {
- if (si[i].seg) {
- free( si[i].seg );
- }
- }
-
- free( si );
-
- return NumSrcFiles;
- } /* CreateSrcLinenumbers() */
-
-
- DWORD
- CreateSegMapFromCoff( PPOINTERS p )
-
- /*++
-
- Routine Description:
-
- Creates the CV segment map. The segment map is used by debuggers
- to aid in address lookups. One segment is created for each COFF
- section in the image.
-
- Arguments:
-
- p - pointer to a POINTERS structure
-
-
- Return Value:
-
- The number of segments in the map.
-
- --*/
-
- {
- int i;
- SGM *sgm;
- SGI *sgi;
- PIMAGE_SECTION_HEADER sh;
-
-
- sgm = (SGM *) p->pCvCurr;
- sgi = (SGI *) ((DWORD)p->pCvCurr + sizeof(SGM));
-
- sgm->cSeg = p->iptrs.numberOfSections;
- sgm->cSegLog = p->iptrs.numberOfSections;
-
- sh = p->iptrs.sectionHdrs;
-
- for (i=0; i<p->iptrs.numberOfSections; i++, sh++) {
- sgi->sgf.fRead = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_READ) == IMAGE_SCN_MEM_READ;
- sgi->sgf.fWrite = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_WRITE) == IMAGE_SCN_MEM_WRITE;
- sgi->sgf.fExecute = (USHORT) (sh->Characteristics & IMAGE_SCN_MEM_EXECUTE) == IMAGE_SCN_MEM_EXECUTE;
- sgi->sgf.f32Bit = 1;
- sgi->sgf.fSel = 0;
- sgi->sgf.fAbs = 0;
- sgi->sgf.fGroup = 1;
- sgi->iovl = 0;
- sgi->igr = 0;
- sgi->isgPhy = (USHORT) i + 1;
- sgi->isegName = 0;
- sgi->iclassName = 0;
- sgi->doffseg = 0;
- sgi->cbSeg = sh->SizeOfRawData;
- sgi++;
- }
-
- UpdatePtrs( p, &p->pCvSegMap, (LPVOID)sgi, i );
-
- return i;
- }
-
-
- LPSTR
- GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s )
-
- /*++
-
- Routine Description:
-
- Extracts the COFF symbol from the image symbol pointer and puts
- the ascii text in the character pointer passed in.
-
-
- Arguments:
-
- Symbol - COFF Symbol Record
- StringTable - COFF string table
- s - buffer for the symbol string
-
-
- Return Value:
-
- void
-
- --*/
-
- {
- DWORD i;
-
- if (Symbol->n_zeroes) {
- for (i=0; i<8; i++) {
- if ((Symbol->n_name[i]>0x1f) && (Symbol->n_name[i]<0x7f)) {
- *s++ = Symbol->n_name[i];
- }
- }
- *s = 0;
- }
- else {
- if (StringTable[Symbol->n_offset] == '?') {
- i = UnDecorateSymbolName( &StringTable[Symbol->n_offset],
- s,
- 255,
- UNDNAME_COMPLETE |
- UNDNAME_NO_LEADING_UNDERSCORES |
- UNDNAME_NO_MS_KEYWORDS |
- UNDNAME_NO_FUNCTION_RETURNS |
- UNDNAME_NO_ALLOCATION_MODEL |
- UNDNAME_NO_ALLOCATION_LANGUAGE |
- UNDNAME_NO_MS_THISTYPE |
- UNDNAME_NO_CV_THISTYPE |
- UNDNAME_NO_THISTYPE |
- UNDNAME_NO_ACCESS_SPECIFIERS |
- UNDNAME_NO_THROW_SIGNATURES |
- UNDNAME_NO_MEMBER_TYPE |
- UNDNAME_NO_RETURN_UDT_MODEL |
- UNDNAME_NO_ARGUMENTS |
- UNDNAME_NO_SPECIAL_SYMS |
- UNDNAME_NAME_ONLY
- );
- if (!i) {
- return NULL;
- }
- } else {
- strcpy( s, &StringTable[Symbol->n_offset] );
- }
- }
-
- return s;
- }
-