dbgdwarf.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 880 行 · 第 1/3 页

C
880
字号
        PutInfo( mod->d.d->pubsym.addr, (void *) &compuhdr,
                                        sizeof( compuhdr_prologue ) );
        mod->d.d->pubsym.addr += sizeof( compuhdr_prologue );
        if( mod->d.d->dasi.size > 0 ) {
            die.abbrev_code = COMPUNIT_ABBREV_CODE;
        } else {
            die.abbrev_code = CU_NOLINE_ABBREV_CODE;
        }
        PutInfo( mod->d.d->pubsym.addr, &die, sizeof( compunit_die ) );
        mod->d.d->pubsym.addr += sizeof( compunit_die );
        if( mod->d.d->dasi.size > 0 ) {
            stmt_list = mod->d.d->dasi.addr
                            + SectionTable[SECT_DEBUG_LINE].start;
            PutInfo( mod->d.d->pubsym.addr, &stmt_list, sizeof( unsigned_32 ) );
            mod->d.d->pubsym.addr += sizeof( unsigned_32 );
        }
        PutInfo( mod->d.d->pubsym.addr, mod->name, namelen + 1 );
        mod->d.d->pubsym.addr += namelen + 1;
        if( mod->d.d->dasi.size > 0 ) {
            mod->d.d->dasi.addr += SectionTable[SECT_DEBUG_LINE].addr;
            stmt_hdr.total_length = mod->d.d->dasi.size - sizeof( unsigned_32 );
            stmt_hdr.version = 2;
            stmt_hdr.prologue_length = sizeof( stmt_prologue )
                        - offsetof( stmt_prologue, minimum_instruction_length )
                        + namelen + 6;
            stmt_hdr.minimum_instruction_length = DW_MIN_INSTR_LENGTH;
            stmt_hdr.default_is_stmt = 1;
            stmt_hdr.line_base = DWLINE_BASE;
            stmt_hdr.line_range = DWLINE_RANGE;
            stmt_hdr.opcode_base = DWLINE_OPCODE_BASE;
            stmt_hdr.standard_opcode_lengths[0] = 0;
            stmt_hdr.standard_opcode_lengths[1] = 1;
            stmt_hdr.standard_opcode_lengths[2] = 1;
            stmt_hdr.standard_opcode_lengths[3] = 1;
            stmt_hdr.standard_opcode_lengths[4] = 1;
            stmt_hdr.standard_opcode_lengths[5] = 0;
            stmt_hdr.standard_opcode_lengths[6] = 0;
            stmt_hdr.standard_opcode_lengths[7] = 0;
            stmt_hdr.standard_opcode_lengths[8] = 0;
            PutInfo( mod->d.d->dasi.addr, (void *) &stmt_hdr,
                                          sizeof( stmt_prologue ) );
            mod->d.d->dasi.addr += sizeof( stmt_prologue );
            buff = alloca( namelen + 6 );
            buff[0] = 0;        // no include directories;
            memcpy( &buff[1], mod->name, namelen + 1 );
            buff[namelen + 2] = 0;      // no directory index
            buff[namelen + 3] = 0;      // no time
            buff[namelen + 4] = 0;      // no length
            buff[namelen + 5] = 0;      // no more strings
            PutInfo( mod->d.d->dasi.addr, buff, namelen + 6 );
            mod->d.d->dasi.addr += namelen + 6;
        }
    }
}

extern void DwarfGenModule( void )
/********************************/
// write out the addr info, and write out the null die at the end of .debug_info
{
    arange_tuple        tuple;
    unsigned            size;
    unsigned_8          nulldie;

    if( CurrMod->modinfo & MOD_DBI_SEEN )
        return;
    if( CurrMod->d.d->arange.size > 0 ) {       // write out terminator arange
        if( FmtData.type & MK_SEGMENTED ) {
            size = sizeof( segmented_arange_tuple );
        } else {
            size = sizeof( flat_arange_tuple );
        }
        memset( &tuple, 0, size );
        PutInfo( CurrMod->d.d->arange.addr, &tuple, size );
    }
    nulldie = 0;
    PutInfo( CurrMod->d.d->pubsym.addr, &nulldie, sizeof( unsigned_8 ) );
}

static void DefAClass( void *_seg )
/*********************************/
{
    seg_leader  *seg = _seg;
    int         index;

    seg->group = AllocGroup( AutoGrpName, &DBIGroups );
    seg->group->grp_addr.seg = 0;
    if( SectionTable[SECT_DEBUG_INFO].size > 0 ) {
        for( index = 0; index < SECT_NUM_SECTIONS; index++ ) {
            if( stricmp( seg->segname, SectionTable[index].name ) == 0 ) {
                seg->dbgtype = index + DWARF_DEBUG_INFO;
                SectionTable[index].start = seg->size;
                break;
            }
        }
    }
}

extern void DwarfDefClass( class_entry *cl, unsigned_32 size )
/************************************************************/
// go through the list of dwarf segments, and make sure VM is allocated for
// all of them.
{
    size = size;        // to avoid a warning
    if( ( cl->flags & CLASS_DEBUG_INFO ) != CLASS_DWARF )
        return;
    DBIClass = cl;
    RingWalk( cl->segs, DefAClass );
}

extern void DwarfAddGlobal( symbol *sym )
/***************************************/
{
    sym = sym;
    CurrMod->d.d->pubsym.size += strlen( sym->name ) + sizeof( symbol_die ) + 1;
    if( FmtData.type & MK_SEGMENTED ) {
        CurrMod->d.d->pubsym.size += sizeof( symbol_seg );
    }
}

static offset GetLinearGroupOffset( group_entry *group )
/************************************************************/
{
    /* gives the absolute offset for ELF, relative for PE and QNX_FLAT;
       perhaps PE and QNX_FLAT should be absolute as well if the
       DWARF format is changed */

    offset      off;

    if( group != NULL ) {
        off = group->linear - group->grp_addr.off;
        if( FmtData.type & MK_ELF ) {
            off += FmtData.base;
        } else {
            off -= Groups->linear;
        }
    }
    return( off );
}

extern void DwarfGenGlobal( symbol *sym, section *sect )
/******************************************************/
{
    symbol_die  die;
    symbol_seg  symseg;
    virt_mem    vmem_addr;
    size_t      len;

    sect = sect;
    if( !( CurrMod->modinfo & MOD_DBI_SEEN ) ) {
        if( ( sym->p.seg == NULL ) || ( sym->p.seg->iscode ) ) {
            die.abbrev_code = LABEL_ABBREV_CODE;
        } else {
            die.abbrev_code = VARIABLE_ABBREV_CODE;
        }
        vmem_addr = CurrMod->d.d->pubsym.addr;
        die.off = sym->addr.off;
        if( FmtData.type & ( MK_PE | MK_QNX_FLAT | MK_ELF ) ) {
            die.off += GetLinearGroupOffset( sym->p.seg->u.leader->group );
        }
        die.isexternal = !( sym->info & SYM_STATIC );
        PutInfo( vmem_addr, &die, sizeof( symbol_die ) );
        vmem_addr += sizeof( symbol_die );
        if( FmtData.type & MK_SEGMENTED ) {
            symseg.len = 3;
            symseg.loc_op = DW_OP_const2u;
            symseg.seg = sym->addr.seg;
            PutInfo( vmem_addr, &symseg, sizeof( symbol_seg ) );
            vmem_addr += sizeof( symbol_seg );
        }
        len = strlen( sym->name ) + 1;
        PutInfo( vmem_addr, sym->name, len );
        CurrMod->d.d->pubsym.addr = vmem_addr + len;
    }
}

static void DwarfAddLines( segdata *seg, void * lines, unsigned size,
                           bool is32bit )
/*******************************************************************/
// calculate the amount of space needed to hold all of the line # info.
{
    ln_off_pair UNALIGN *lineptr;
    unsigned_32         dwsize;
    char                buff[ 3 + 2 * MAX_LEB128 ];
    dw_linenum_delta    linedelta;
    dw_addr_delta       addrdelta;
    ln_off_386          prevline;

    seg = seg;
    lineptr = lines;
    prevline.off = 0;
    prevline.linnum = 1;
    if( FmtData.type & MK_286 ) {
        dwsize = 13;    // start and end sequence with 16-bit offset
    } else {
        dwsize = 15;    // start and end sequence with 32-bit offset
    }
    if( !( FmtData.type & MK_SEGMENTED ) ) {
        dwsize -= 5;    // size of LNE_segment burst
    }
    while( size > 0 ) {
        if( is32bit ) {
            linedelta = (signed_32) lineptr->_386.linnum - prevline.linnum;
            addrdelta = lineptr->_386.off - prevline.off;
            lineptr++;
            size -= sizeof( ln_off_386 );
        } else {
            linedelta = (signed_32) lineptr->_286.linnum - prevline.linnum;
            addrdelta = lineptr->_286.off - prevline.off;
            lineptr = (void *)( (char *)lineptr + sizeof( ln_off_286 ) );
            size -= sizeof( ln_off_286 );
        }
        prevline.linnum += linedelta;
        prevline.off += addrdelta;
        dwsize += DWLineGen( linedelta, addrdelta, buff );
    }
    CurrMod->d.d->dasi.size += dwsize;
}

extern void DwarfGenLines( segdata *seg, void *lines, unsigned size,
                           bool is32bit )
/******************************************************************/
{
    ln_off_pair UNALIGN *lineptr;
    unsigned            dwsize;
    dw_linenum_delta    linedelta;
    dw_addr_delta       addrdelta;
    virt_mem            vmem_addr;
    ln_off_386          prevline;
    offset              off;
    char                buff[ 3 + 2 * MAX_LEB128 ];

    seg = seg;
    if( CurrMod->modinfo & MOD_DBI_SEEN )
        return;
    prevline.off = 0;
    prevline.linnum = 1;
    vmem_addr = CurrMod->d.d->dasi.addr;
    if( FmtData.type & MK_286 ) {
        dwsize = 3;
    } else {
        dwsize = 5;
    }
    buff[0] = 0;        // extended opcode
    buff[1] = dwsize;
    buff[2] = DW_LNE_set_address;
    if( FmtData.type & MK_286 ) {
        *( (unsigned_16 *)&buff[3] ) = seg->a.delta + seg->u.leader->seg_addr.off;
    } else {
        off = seg->a.delta + seg->u.leader->seg_addr.off;
        if( FmtData.type & ( MK_PE | MK_QNX_FLAT | MK_ELF ) ) {
            off += GetLinearGroupOffset( seg->u.leader->group );
        }
        *( (unsigned_32 *)&buff[3] ) = off;
    }
    dwsize += 2;
    PutInfo( vmem_addr, buff, dwsize );
    vmem_addr += dwsize;
    if( FmtData.type & MK_SEGMENTED ) {
        buff[1] = 3;
        buff[2] = DW_LNE_set_segment;
        *( (unsigned_16 *)&buff[3] ) = seg->u.leader->seg_addr.seg;
        PutInfo( vmem_addr, buff, 5 );
        vmem_addr += 5;
    }
    lineptr = (ln_off_pair *) lines;
    while( size > 0 ) {
        if( is32bit ) {
            linedelta = (signed_32) lineptr->_386.linnum - prevline.linnum;
            addrdelta = lineptr->_386.off - prevline.off;
            lineptr++;
            size -= sizeof( ln_off_386 );
        } else {
            linedelta = (signed_32) lineptr->_286.linnum - prevline.linnum;
            addrdelta = lineptr->_286.off - prevline.off;
            lineptr = (void *)( (char *)lineptr + sizeof( ln_off_286 ) );
            size -= sizeof( ln_off_286 );
        }
        prevline.linnum += linedelta;
        prevline.off += addrdelta;
        dwsize = DWLineGen( linedelta, addrdelta, buff );
        PutInfo( vmem_addr, buff, dwsize );
        vmem_addr += dwsize;
    }
    buff[0] = 0;        // extended opcode
    buff[1] = 1;        // size 1
    buff[2] = DW_LNE_end_sequence;
    PutInfo( vmem_addr, buff, 3 );
    CurrMod->d.d->dasi.addr = vmem_addr + 3;
}

static void DwarfAddAddrInit( segdata *sdata, void *cookie )
/**********************************************************/
{
    sdata = sdata;

⌨️ 快捷键说明

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