File:  [WindowsNT SDKs] / mstools / samples / sdktools / image / drwatson / symbols.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:27:30 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

/*++

Copyright (c) 1993  Microsoft Corporation

Module Name:

    symbols.c

Abstract:

    This file contains all support for the symbol table.

Author:

    Wesley Witt (wesw) 1-May-1993

Environment:

    User Mode

--*/

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <imagehlp.h>

#include "drwatson.h"
#include "proto.h"
#include "cv.h"
#include "messages.h"


#define n_name          N.ShortName
#define n_zeroes        N.Name.Short
#define n_nptr          N.LongName[1]
#define n_offset        N.Name.Long

void GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s );
PSYMBOL AllocSym( DWORD symSize, PSYMBOL *symHead, PSYMBOL *symTail );
int _CRTAPI1 SymbolCompare( const void *arg1, const void *arg2 );


PSYMBOL
SymbolSearch( DWORD key, PSYMBOL *base, DWORD num )
{
    PSYMBOL    *lo   = base;
    PSYMBOL    *hi   = base + (num - 1);
    PSYMBOL    *mid  = NULL;
    DWORD      half  = 0;

    while (lo <= hi) {
        if (half = num / 2) {
            mid = lo + (num & 1 ? half : (half - 1));
            if ((key >= (*mid)->addr) &&
                (key < ((*mid)->addr + (*mid)->size))) {
                return *mid;
            }
            if (key < (*mid)->addr) {
                hi = mid - 1;
                num = num & 1 ? half : half-1;
            }
            else {
                lo = mid + 1;
                num = half;
            }
        }
        else
        if (num) {
            if ((key >= (*lo)->addr) &&
                (key < ((*lo)->addr + (*lo)->size))) {
                return *lo;
            }
            else {
                break;
            }
        }
        else {
                break;
        }
    }
    return NULL;
}

PSYMBOL
GetSymFromAddr( DWORD dwAddr, PDWORD pdwDisplacement, PMODULEINFO mi )
{
    PSYMBOL sym = NULL;

    if (mi == NULL) {
        return sym;
    }

    sym = SymbolSearch( dwAddr, mi->symbolTable, mi->numsyms );
    if (sym !=NULL) {
        *pdwDisplacement = dwAddr - sym->addr;
    }

    return sym;
}

PMODULEINFO
GetModuleForPC( PDEBUGPACKET dp, DWORD dwPcAddr )
{
    PMODULEINFO mi = dp->miHead;

    Assert( mi != NULL );
    while (mi) {
        if ((dwPcAddr >= mi->dwLoadAddress) &&
            (dwPcAddr <= mi->dwLoadAddress + mi->dwImageSize)) {
               return mi;
        }
        mi = mi->next;
    }

    return NULL;
}

PSYMBOL
GetSymFromAddrAllContexts( DWORD dwAddr, PDWORD pdwDisplacement, PDEBUGPACKET dp )
{
    PMODULEINFO mi = GetModuleForPC( dp, dwAddr );
    if (mi == NULL) {
        return NULL;
    }
    return GetSymFromAddr( dwAddr, pdwDisplacement, mi );
}

void
DumpSymbols( PDEBUGPACKET dp )
{
    DWORD         i;
    PSYMBOL       *sym;
    char          *szSymName;
    PMODULEINFO   mi;


    lprintf( MSG_SYMBOL_TABLE );

    mi = dp->miHead;
    while (mi) {
        lprintfs( "%s\r\n", mi->szName );
        for (i=0,sym=mi->symbolTable; i<mi->numsyms; i++,sym++) {
            szSymName = UnDName( &(*sym)->szName[1] );
            lprintfs( "%08x    %s\r\n", (*sym)->addr, szSymName );
        }
        lprintfs( "\r\n" );
        mi = mi->next;
    }

    return;
}

PSYMBOL
AllocSym( DWORD symSize, PSYMBOL *symHead, PSYMBOL *symTail )
{
    PSYMBOL sym;

    sym = (PSYMBOL) malloc( sizeof(SYMBOL)+symSize );
    if (sym == NULL) {
        return NULL;
    }
    memset( sym, 0, sizeof(SYMBOL)+symSize );

    if (*symHead == NULL) {
        *symTail = *symHead = sym;
        return sym;
    }
    else {
        (*symTail)->next = sym;
        *symTail = sym;
        return sym;
    }
    return NULL;
}

BOOL
LoadFpoData( PMODULEINFO mi, PFPO_DATA start, DWORD size )
{
    mi->pFpoData = (PFPO_DATA) malloc( size );

    if (mi->pFpoData == NULL) {
        return FALSE;
    }

    memcpy( mi->pFpoData, start, size );

    mi->dwEntries = size / sizeof(FPO_DATA);

    return TRUE;
}

BOOL
LoadExceptionData( PMODULEINFO mi, PRUNTIME_FUNCTION start, DWORD size )
{
    DWORD               cFunc;
    DWORD               index;
    PRUNTIME_FUNCTION   rf;
    PRUNTIME_FUNCTION   tf;


    if (size == 0) {
        return FALSE;
    }

    cFunc = size / sizeof(RUNTIME_FUNCTION);

    //
    // Find the start of the padded page (end of the real data)
    //
    rf = tf = start;
    for(index=0; index<cFunc && tf->BeginAddress; tf++,index++) {
        ;
    }

    if (index<cFunc) {
        cFunc = index;
        size  = index * sizeof(RUNTIME_FUNCTION);
    }

    mi->pExceptionData = (PRUNTIME_FUNCTION) malloc( size );
    if (mi->pExceptionData == NULL) {
        return FALSE;
    }

    memcpy( mi->pExceptionData, rf, size );

    mi->dwEntries = cFunc;

    return TRUE;
}

BOOL
LoadCoffSymbols( PMODULEINFO     mi,
                 PUCHAR          stringTable,
                 PIMAGE_SYMBOL   allSymbols,
                 DWORD           numberOfSymbols
               )
{
    PIMAGE_SYMBOL       NextSymbol;
    PIMAGE_SYMBOL       Symbol;
    PIMAGE_AUX_SYMBOL   AuxSymbol;
    SYMBOL              *sym;
    char                szSymName[256];
    DWORD               len;
    DWORD               numaux;
    DWORD               i;
    DWORD               j;
    DWORD               addr;
    PSYMBOL             *symbolTable;
    PSYMBOL             *symbolTable2;
    PSYMBOL             symHead = NULL;
    PSYMBOL             symTail = NULL;

    Assert( mi != NULL );
    NextSymbol = allSymbols;
    for (i= 0; i < numberOfSymbols; i++) {
        Symbol = NextSymbol++;
        if (Symbol->StorageClass == IMAGE_SYM_CLASS_EXTERNAL && Symbol->SectionNumber > 0) {
            GetSymName( Symbol, stringTable, szSymName );
            addr = Symbol->Value + mi->dwLoadAddress;
            len = strlen( szSymName );
            sym = AllocSym ( len+1, &symHead, &symTail );
            sym->szName[0] = (UCHAR) len;
            strcpy( &sym->szName[1], szSymName );
            sym->addr = addr;
            mi->numsyms++;
        }
        if (numaux = Symbol->NumberOfAuxSymbols) {
            for (j=numaux; j; --j) {
                AuxSymbol = (PIMAGE_AUX_SYMBOL) NextSymbol;
                NextSymbol++;
                ++i;
            }
        }
    }

    mi->symbolTable = (PSYMBOL*) malloc( mi->numsyms * sizeof(PSYMBOL) );
    Assert( mi->symbolTable != NULL );

    sym = symHead;
    symbolTable = mi->symbolTable;
    while (sym) {
        *symbolTable = sym;
        symbolTable++;
        sym = sym->next;
    }

    qsort( (void*)mi->symbolTable, mi->numsyms, sizeof(PSYMBOL), SymbolCompare );

    for (i=0,symbolTable=mi->symbolTable; i<mi->numsyms; i++,symbolTable++) {
        if (i+1 < mi->numsyms) {
            symbolTable2 = symbolTable+1;
            (*symbolTable)->size = (*symbolTable2)->addr - (*symbolTable)->addr;
        }
    }

    return TRUE;
}

BOOL
LoadCodeViewSymbols( PMODULEINFO            mi,
                     PUCHAR                 pCvData,
                     PIMAGE_SECTION_HEADER  sectionHdrs,
                     DWORD                  numSections
                   )
{
    OMFSignature           *omfSig;
    OMFDirHeader           *omfDirHdr;
    OMFDirEntry            *omfDirEntry;
    DATASYM32              *dataSym;
    OMFSymHash             *omfSymHash;
    SYMBOL                 *sym;
    DWORD                  i;
    DWORD                  j;
    DWORD                  k;
    DWORD                  addr;
    PSYMBOL                *symbolTable;
    PSYMBOL                *symbolTable2;
    PIMAGE_SECTION_HEADER  sh;
    PSYMBOL                symHead = NULL;
    PSYMBOL                symTail = NULL;


    Assert( mi != NULL );
    omfSig = (OMFSignature*) pCvData;
    if ((strncmp( omfSig->Signature, "NB08", 4 ) != 0) &&
        (strncmp( omfSig->Signature, "NB09", 4 ) != 0)) {
        return FALSE;
    }

    omfDirHdr = (OMFDirHeader*) ((DWORD)omfSig + (DWORD)omfSig->filepos);
    omfDirEntry = (OMFDirEntry*) ((DWORD)omfDirHdr + sizeof(OMFDirHeader));

    for (i=0; i<omfDirHdr->cDir; i++,omfDirEntry++) {
        if (omfDirEntry->SubSection == sstGlobalPub) {
            omfSymHash = (OMFSymHash*) ((DWORD)omfSig + omfDirEntry->lfo);
            dataSym = (DATASYM32*) ((DWORD)omfSig + omfDirEntry->lfo + sizeof(OMFSymHash));
            for (j=sizeof(OMFSymHash); j<=omfSymHash->cbSymbol; ) {
                sym = AllocSym ( dataSym->name[0]+1, &symHead, &symTail );
                if (sym != NULL) {
                    for (k=0,addr=0,sh=sectionHdrs; k<numSections; k++, sh++) {
                        if (k+1 == dataSym->seg) {
                            addr = sh->VirtualAddress;
                        }
                    }
                    addr += (dataSym->off + mi->dwLoadAddress);
                    memcpy( sym->szName, dataSym->name, dataSym->name[0]+1 );
                    sym->addr = addr;
                    j += dataSym->reclen + 2;
                    dataSym = (DATASYM32*) ((DWORD)dataSym + dataSym->reclen + 2);
                    mi->numsyms++;
                }
            }
            break;
        }
    }


    mi->symbolTable = (PSYMBOL*) malloc( mi->numsyms * sizeof(PSYMBOL) );
    if (mi->symbolTable == NULL) {
        return FALSE;
    }

    sym = symHead;
    symbolTable = mi->symbolTable;
    i = 0;
    while (sym) {
        i++;
        *symbolTable = sym;
        symbolTable++;
        sym = sym->next;
    }

    qsort( (void*)mi->symbolTable, mi->numsyms, sizeof(PSYMBOL), SymbolCompare );

    for (i=0,symbolTable=mi->symbolTable; i<mi->numsyms; i++,symbolTable++) {
        if (i+1 < mi->numsyms) {
            symbolTable2 = symbolTable+1;
            (*symbolTable)->size = (*symbolTable2)->addr - (*symbolTable)->addr;
        }
    }

    return TRUE;
}

void
GetSymName( PIMAGE_SYMBOL Symbol, PUCHAR StringTable, char *s )
{
    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 {
        strcpy( s, &StringTable[Symbol->n_offset] );
    }
}

int
_CRTAPI1
SymbolCompare( const void *arg1, const void *arg2 )
{
    if ((*(PSYMBOL*)arg1)->addr < (*(PSYMBOL*)arg2)->addr) {
        return -1;
    }
    if ((*(PSYMBOL*)arg1)->addr > (*(PSYMBOL*)arg2)->addr) {
        return 1;
    }
    return 0;
}

char *
UnDName (char * dName)
{
    static char outBuf[512];
    char *p;

    if (*dName == '_') {
        ++dName;
        strcpy(outBuf, dName);
        p = strchr(outBuf, '@');
        if (p) {
            *p = '\0';
        }
    }
    else
    if(UnDecorateSymbolName( dName,
                             outBuf,
                             sizeof(outBuf),
                             UNDNAME_COMPLETE ) == 0 ) {
        return NULL;
    }

    return  outBuf;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.