drgettab.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 258 行

C
258
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  DWARF file table utility functions.
*
****************************************************************************/


#include "drpriv.h"
#include "drutils.h"
#include <string.h>
#include "walloca.h"

// these are the increments in which the dynamically growing tables will
// grow. NOTE that the code relies on VBL_ARRAY_DELTA being a power of 2

#define VBL_ARRAY_DELTA     0x10
#define VBL_ARRAY_MASK      (VBL_ARRAY_DELTA - 1)

file_info               FileNameTable;

static bool GrabLineAddr( dr_handle abbrev, dr_handle mod, mod_scan_info *x,
                          void *_data )
/***************************************************************************/
/* this is called by ScanCompileUnit with abbrevptr and dataptr pointing at
 * the start of a compile unit die.  This picks out the line number info.
 * offset, and stores it in data */
{
    long    *data = _data;

    x = x;      // to avoid a warning
    if( DWRScanForAttrib( &abbrev, &mod, DW_AT_stmt_list ) != 0 ) {
        *data = DWRReadConstant( abbrev, mod );
    }
    return( FALSE );    // do not continue with the search.
}

extern void DWRInitFileTable( file_table *tab )
/*********************************************/
{
    tab->len = 0;
    tab->tab = DWRALLOC( VBL_ARRAY_DELTA * sizeof( filetab_entry ) );
}

extern void DWRFiniFileTable( file_table *tab, bool freenames )
/*************************************************************/
{
    int                 index;

    if( freenames ) {
        for( index = 0; index < tab->len; index++ ) {
            DWRFREE( tab->tab[index].name );
        }
    }
    if( tab->tab != NULL ) {
        DWRFREE( tab->tab );
    }
}

static void GrowTable( file_table *tab )
/**************************************/
{
    tab->len++;
    if( !(tab->len & VBL_ARRAY_MASK) ) {        // it will overflow
        tab->tab = DWRREALLOC( tab->tab,
                   (tab->len + VBL_ARRAY_DELTA) * sizeof(filetab_entry) );
    }
}

extern unsigned_16 DWRAddFileName( char *name, file_table *tab )
/**************************************************************/
{
    unsigned    index;
    char        **names;

    names = (char **)tab->tab;
    index = 0;
    while( index < tab->len ) {
        if( strcmp( name, *names ) == 0 ) {
            DWRFREE( name );
            return( index );
        }
        index++;
        names++;
    }
    GrowTable( tab );
    tab->tab[index].name = name;
    return( index );
}

static void DWRInsertIndex( unsigned_16 idx, file_table *tab, unsigned where )
/*************************************************************************/
{
    if( where == TAB_IDX_FNAME ) {
        tab->tab[tab->len - 1].idx.fnameidx = idx;
    } else {
        tab->tab[tab->len - 1].idx.pathidx = idx;
    }
}

extern void DWRAddIndex( unsigned_16 idx, file_table *tab, unsigned where )
/*************************************************************************/
{
    GrowTable( tab );
    DWRInsertIndex( idx, tab, where );
}

extern unsigned_16 DWRIndexPath( unsigned_16 idx, file_table *tab )
/*****************************************************************/
{
    return( tab->tab[idx].idx.pathidx );
}

extern unsigned_16 DWRIndexFile( unsigned_16 idx, file_table *tab )
/*****************************************************************/
{
    return( tab->tab[idx].idx.fnameidx );
}

extern char * DWRIndexFileName( unsigned_16 idx, file_table *tab )
/****************************************************************/
{
    return( tab->tab[idx].name );
}

static void DWRTrimTableSize( file_table *tab )
/*********************************************/
{
    tab->tab = DWRREALLOC( tab->tab, tab->len * sizeof(filetab_entry) );
}

static void ReadNameEntry( dr_handle *start, file_info *nametab,
                           file_table *idxtab, file_table *maptab )
/*****************************************************************/
{
    char        *name;
    unsigned_16 idx;

    name = DWRCopyString( start );
    idx = DWRAddFileName( name, &nametab->fnametab );
    DWRAddIndex( idx, idxtab, TAB_IDX_FNAME );
    idx = DWRVMReadULEB128( start );
    idx = DWRIndexPath( idx, maptab );
    DWRInsertIndex( idx, idxtab, TAB_IDX_PATH );
    DWRVMSkipLEB128( start );   // skip time
    DWRVMSkipLEB128( start );   // skip length
}

extern void DWRScanFileTable( dr_handle start, file_info *nametab,
                              file_table *idxtab )
/****************************************************************/
// find the filenames in the line information, and return them in a table
{
    dr_handle   finish;
    file_table  curridxmap;
    char        *name;
    unsigned    index;
    unsigned    length;
    unsigned_8  *oparray;
    unsigned_8  op_base;
    unsigned_8  value;
    long        stmt_offset;

    stmt_offset = -1;
    DWRGetCompileUnitHdr( start, GrabLineAddr, &stmt_offset );
    if( stmt_offset == -1 ) {
        return;
    }
    start = DWRCurrNode->sections[DR_DEBUG_LINE].base;
    start += stmt_offset;
    finish = start + DWRVMReadDWord( start );
    start += 4 + 2 + 4 + 1 + 1 + 1 + 1;         // skip the start of the header
    op_base = DWRVMReadByte( start );
    oparray = __alloca( op_base - 1 );
    start++;
    for( index = 0; index < op_base - 1; index++ ) {
        oparray[index] = DWRVMReadByte( start );
        start++;
    }
    DWRInitFileTable( &curridxmap );
    while( start < finish ) {           // get directory table
        value = DWRVMReadByte( start );
        if( value == 0 ) break;
        name = DWRCopyString( &start );
        index = DWRAddFileName( name, &nametab->pathtab );
        DWRAddIndex( index, &curridxmap, TAB_IDX_PATH );
    }
    start++;
    while( start < finish ) {           // get filename table
        value = DWRVMReadByte( start );
        if( value == 0 ) break;
        ReadNameEntry( &start, nametab, idxtab, &curridxmap );
    }
    start++;
    while( start < finish ) {   // now go through the statement program
        value = DWRVMReadByte( start );
        start++;
        if( value == 0 ) {      // it's an extended opcode
            length = DWRVMReadULEB128( &start );
            value = DWRVMReadByte( start );
            if( value == DW_LNE_define_file ) {
                start++;
                ReadNameEntry( &start, nametab, idxtab, &curridxmap );
            } else {
                start += length;
            }
        } else if( value < op_base ) {  // it is a standard opcode
            if( value == DW_LNS_fixed_advance_pc ) {
                start += sizeof(unsigned_16);    // it is a fixed size
            } else {    // it is a variable # of blocks
                value = oparray[value-1];
                while( value > 0 ) {
                    DWRVMSkipLEB128( &start );
                    value--;
                }
            }
        }       // else it was a special op, and thus only 1 byte long
    }
    DWRTrimTableSize( idxtab );
    DWRFiniFileTable( &curridxmap, FALSE );
}

extern char * DWRFindFileName( unsigned fileno, dr_handle entry )
/***************************************************************/
{
    compunit_info   *compunit;

    if( fileno != 0 ) {
        compunit = DWRFindCompileInfo( entry );
        fileno = DWRIndexFile( fileno - 1, &compunit->filetab );
        return( DWRIndexFileName( fileno, &FileNameTable.fnametab ) );
    }
    return( NULL );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?