Beispiel #1
0
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) == 0 ) {
        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.u.vm_ptr;
        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) == 0 );
        PutInfo( vmem_addr, &die, sizeof( symbol_die ) );
        vmem_addr += sizeof( symbol_die );
        if( FmtData.type & MK_SEGMENTED ) {
            symseg.len_u8 = 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.u.vm_ptr = vmem_addr + len;
    }
}
Beispiel #2
0
static void GenSrcModHeader( void )
/*********************************/
// emit header for line number information now that we know where everything
// is.
{
    cheesy_module_header        mod_hdr;
    cheesy_file_table           file_tbl;
    cheesy_mapping_table        map_tbl;
    unsigned                    adjust;
    unsigned_32                 buff;

    if( LineInfo.linestart == 0 )
        return;
    memset( &mod_hdr, 0, sizeof( mod_hdr ) );
    mod_hdr.cFile = 1;
    mod_hdr.cSeg = 1;
    mod_hdr.range[0] = LineInfo.range;
    mod_hdr.baseSrcFile[0] = sizeof( mod_hdr );
    mod_hdr.seg[0] = LineInfo.seg;
    mod_hdr.pad = 0;
    PutInfo( LineInfo.linestart, &mod_hdr, sizeof( mod_hdr ) );
    LineInfo.linestart += sizeof( mod_hdr );
    file_tbl.cSeg = 1;
    file_tbl.pad = 0;
    file_tbl.range[0] = LineInfo.range;
    file_tbl.name[0] = strlen( CurrMod->name );
    file_tbl.baseSrcLn[0] = sizeof( mod_hdr ) +
                    ROUND_UP( sizeof( file_tbl ) + file_tbl.name[0], 4 );
    PutInfo( LineInfo.linestart, &file_tbl, sizeof( file_tbl ) );
    LineInfo.linestart += sizeof( file_tbl );
    PutInfo( LineInfo.linestart, CurrMod->name, file_tbl.name[0] );
    LineInfo.linestart += file_tbl.name[0];
    adjust = file_tbl.baseSrcLn[0] - sizeof( mod_hdr ) - sizeof( file_tbl )
                - file_tbl.name[0];
    if( adjust != 0 ) {
        buff = 0;
        PutInfo( LineInfo.linestart, &buff, adjust );
        LineInfo.linestart += adjust;
    }
    map_tbl.Seg = mod_hdr.seg[0];
    map_tbl.cPair = CurrMod->d.cv->numlines;
    PutInfo( LineInfo.linestart, &map_tbl, sizeof( map_tbl ) );
    memset( &LineInfo, 0, sizeof( LineInfo ) );
}
Beispiel #3
0
static void CVGenAddrAdd( segdata *sdata, offset delta, offset size, void *_info, bool isnewmod )
/***********************************************************************************************/
{
    cv_seginfo *info = _info;
    if( !isnewmod )
        return;
    info->cbSeg = size;
    PutInfo( sdata->o.mod->d.cv->segloc, info, sizeof( cv_seginfo ) );
    sdata->o.mod->d.cv->segloc += sizeof( cv_seginfo );
    info->offset = sdata->u.leader->seg_addr.off + delta;
}
Beispiel #4
0
static void DefNosymComdats( void *_snode, void *dummy )
/******************************************************/
{
    segnode             *snode = _snode;
    segdata             *sdata;

    dummy = dummy;
    sdata = snode->entry;
    if( sdata == NULL || (snode->info & SEG_DEAD) )
        return;
    if( sdata->iscdat && !sdata->hascdatsym && ( snode->contents != NULL )) {
        sdata->u1.vm_ptr = AllocStg( sdata->length );
        PutInfo( sdata->u1.vm_ptr, snode->contents, sdata->length );
    }
}
Beispiel #5
0
static void WriteOutTokElem( void *_elem, void *buf )
/***************************************************/
{
    TocEntry   *elem = _elem;
    offset      addr;
    segdata *   sdata;
    seg_leader *leader;

    if( elem->e.sdata ) {
        sdata = elem->e.sdata;
        leader = sdata->u.leader;
        addr = elem->e.u.off + sdata->a.delta + leader->group->linear
                        + leader->seg_addr.off +  FmtData.base;
    } else {
        addr = SymbolAbsAddr( elem->e.u.sym );
    }
    DbgAssert( elem->pos >= 0 );
    PutInfo( (*((virt_mem *)buf)) + elem->pos, &addr, sizeof( addr ) );
}
Beispiel #6
0
void WriteToc( virt_mem buf )
/**********************************/
{
    if( Toc == NULL )
        return;
    WalkHTableCookie( Toc, WriteOutTokElem, &buf );
#if 0
    if( (LinkState & HAVE_PPC_CODE) && (FmtData.type & MK_OS2) ) {
        // Development temporarly on hold
        offset res[GOT_RESERVED_SIZE / sizeof( offset )] = { 0 };
        enum { zero = GOT_RESERVED_NEG_SIZE / sizeof( offset ) };
        enum { blrl_opcode = 0x4E800021 };

        DbgAssert( TocShift >= GOT_RESERVED_NEG_SIZE );

        res[zero - 1] = blrl_opcode;
        res[zero] = IDataGroup->linear + FmtData.base;
        PutInfo( buf + TocShift - GOT_RESERVED_NEG_SIZE, res, GOT_RESERVED_SIZE );
    }
#endif
}
Beispiel #7
0
void CVGenLines( lineinfo *info )
/*******************************/
// called during pass 2 linnum processing
{
    ln_off_pair UNALIGN *pair;
    unsigned_32         temp_off;
    unsigned_16         temp_num;
    offset              adjust;
    unsigned long       cvsize;
    unsigned            size;
    segdata             *seg;

    seg = info->seg;
    size = info->size & ~LINE_IS_32BIT;

    if( !( CurrMod->modinfo & DBI_LINE ) )
        return;
    adjust = seg->a.delta + seg->u.leader->seg_addr.off;
    if( LineInfo.offbase == 0 ) { // this is our first time through.
        LineInfo.seg = GetCVSegment( seg->u.leader );
        LineInfo.linestart = SectAddrs[CVSECT_MISC];
        cvsize = sizeof( cheesy_module_header ) + sizeof( cheesy_mapping_table )
            + ROUND_UP( sizeof( cheesy_file_table ) + strlen( CurrMod->name ), 4 );
        LineInfo.offbase = SectAddrs[CVSECT_MISC] + cvsize;
        LineInfo.numbase = LineInfo.offbase
                                + CurrMod->d.cv->numlines * sizeof( unsigned_32 );
        cvsize += CurrMod->d.cv->numlines * sizeof( unsigned_32 );
        cvsize += ROUND_UP( CurrMod->d.cv->numlines * sizeof( unsigned_16 ), 4 );
        GenSubSection( sstSrcModule, cvsize );
        SectAddrs[CVSECT_MISC] += cvsize;
        LineInfo.range.start = adjust;
        LineInfo.range.end = adjust + seg->length;
    } else {
        if( adjust < LineInfo.range.start ) {
            LineInfo.range.start = adjust;
        }
        if( adjust + seg->length > LineInfo.range.end ) {
            LineInfo.range.end = adjust + seg->length;
        }
    }
    pair = (ln_off_pair *)info->data;
    if( info->size & LINE_IS_32BIT ) {
        while( size > 0 ) {
            pair->_386.off += adjust;
            if( pair->_386.off < LineInfo.prevaddr ) {
                LineInfo.needsort = TRUE;
            }
            LineInfo.prevaddr = pair->_386.off;
            _HostU32toTarg( pair->_386.off, temp_off );
            _HostU16toTarg( pair->_386.linnum, temp_num );
            PutInfo( LineInfo.offbase, &temp_off, sizeof( unsigned_32 ) );
            PutInfo( LineInfo.numbase, &temp_num, sizeof( unsigned_16 ) );
            LineInfo.offbase += sizeof( unsigned_32 );
            LineInfo.numbase += sizeof( unsigned_16 );
            pair = (void *)( (char *)pair + sizeof( ln_off_386 ) );
            size -= sizeof( ln_off_386 );
        }
    } else {
        while( size > 0 ) {
            pair->_286.off += adjust;
            if( pair->_286.off < LineInfo.prevaddr ) {
                LineInfo.needsort = TRUE;
            }
            LineInfo.prevaddr = pair->_286.off;
            _HostU16toTarg( pair->_286.off, temp_off );
            _HostU16toTarg( pair->_286.linnum, temp_num );
            PutInfo( LineInfo.offbase, &temp_off, sizeof( unsigned_32 ) );
            PutInfo( LineInfo.numbase, &temp_num, sizeof( unsigned_16 ) );
            LineInfo.offbase += sizeof( unsigned_32 );
            LineInfo.numbase += sizeof( unsigned_16 );
            pair = (void *)( (char *)pair + sizeof( ln_off_286 ) );
            size -= sizeof( ln_off_286 );
        }
    }
}
Beispiel #8
0
static void DumpInfo( unsigned sect, void *data, unsigned_32 len )
/****************************************************************/
{
    PutInfo( SectAddrs[sect], data, len );
    SectAddrs[sect] += len;
}
Beispiel #9
0
static void AllocSeg( void *_snode, void *dummy )
/***********************************************/
{
    segnode             *snode = _snode;
    segdata             *sdata;
    char                *clname;
    char                *sname;
    group_entry         *group;
    bool                isdbi;

    dummy = dummy;
    sdata = snode->entry;
    if( sdata == NULL )
        return;
    sname = sdata->u.name;
    if( CurrMod->modinfo & MOD_IMPORT_LIB ) {
        if( sdata->isidata || sdata->iscode ) {
            if( sdata->iscode ) {
                snode->info |= SEG_CODE;
            }
            snode->info |= SEG_DEAD;
            snode->entry = NULL;
            FreeSegData( sdata );
            return;
        }
    }
    isdbi = false;
    if( memicmp( CoffDebugPrefix, sdata->u.name,
                 sizeof(CoffDebugPrefix) - 1 ) == 0 ) {
        if( CurrMod->modinfo & MOD_IMPORT_LIB ) {
            snode->info |= SEG_DEAD;
            snode->entry = NULL;
            FreeSegData( sdata );
            return;
        }
        isdbi = true;
        if( stricmp(CoffDebugSymName, sdata->u.name ) == 0 ) {
            clname = _MSLocalClass;
        } else if( stricmp(CoffDebugTypeName, sdata->u.name ) == 0 ) {
            clname = _MSTypeClass;
        } else {
            clname = _DwarfClass;
        }
    } else if( memicmp( TLSSegPrefix, sdata->u.name,
                        sizeof(TLSSegPrefix) - 1 ) == 0 ) {
        clname = TLSClassName;
    } else if( sdata->iscode ) {
        clname = CodeClassName;
    } else if( sdata->isuninit ) {
        clname = BSSClassName;
    } else {
        clname = DataClassName;
        if( memcmp( sname, CoffPDataSegName, sizeof(CoffPDataSegName) ) == 0 ) {
            sdata->ispdata = true;
        } else if( memcmp(sname, CoffReldataSegName,
                                   sizeof(CoffReldataSegName) ) == 0 ) {
            sdata->isreldata = true;
        }
    }
    AllocateSegment( snode, clname );
    if( clname == TLSClassName ) {
        group = GetGroup( TLSGrpName );
        AddToGroup( group, snode->entry->u.leader );
    } else if( !sdata->iscode && !isdbi ) {
        group = GetGroup( DataGrpName );
        AddToGroup( group, snode->entry->u.leader );
    }
    if( sdata->isuninit ) {
        snode->contents = NULL;
    } else {
        snode->entry->u.leader->info |= SEG_LXDATA_SEEN;
        if( !sdata->isdead ) {
            ORLSecGetContents( snode->handle, &snode->contents );
            if( !sdata->iscdat && ( snode->contents != NULL )) {
                PutInfo( sdata->u1.vm_ptr, snode->contents, sdata->length );
            }
        }
    }
}
Beispiel #10
0
void DwarfGenLines( lineinfo *info )
/**********************************/
{
    ln_off_pair _WCUNALIGNED *lineptr;
    unsigned            dwsize;
    dw_linenum_delta    linedelta;
    dw_addr_delta       addrdelta;
    virt_mem            vmem_addr;
    ln_off_386          prevline;
    offset              off;
    unsigned_8          buff[ 3 + 2 * MAX_LEB128 ];
    unsigned            size;
    segdata             *seg;
    unsigned            item_size;

    if( CurrMod->modinfo & MOD_DBI_SEEN )
        return;

    seg = info->seg;
    prevline.off = 0;
    prevline.linnum = 1;
    vmem_addr = CurrMod->d.d->dasi.u.vm_ptr;
    if( FmtData.type & MK_16BIT ) {
        dwsize = 3;
    } else {
        dwsize = 5;
    }
    buff[0] = 0;        // extended opcode
    buff[1] = dwsize;
    buff[2] = DW_LNE_set_address;
    if( FmtData.type & MK_16BIT ) {
        *( (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_WATCOM_set_segment_OLD;
//        buff[2] = DW_LNE_WATCOM_set_segment;
        *( (unsigned_16 *)&buff[3] ) = seg->u.leader->seg_addr.seg;
        PutInfo( vmem_addr, buff, 5 );
        vmem_addr += 5;
    }
    if( info->size & LINE_IS_32BIT ) {
        item_size = sizeof( ln_off_386 );
    } else {
        item_size = sizeof( ln_off_286 );
    }
    lineptr = (ln_off_pair *)info->data;
    for( size = info->size & ~LINE_IS_32BIT; size > 0; size -= item_size ) {
        if( info->size & LINE_IS_32BIT ) {
            linedelta = (signed_32) lineptr->_386.linnum - prevline.linnum;
            addrdelta = lineptr->_386.off - prevline.off;
        } else {
            linedelta = (signed_32) lineptr->_286.linnum - prevline.linnum;
            addrdelta = lineptr->_286.off - prevline.off;
        }
        prevline.linnum += linedelta;
        prevline.off += addrdelta;
        dwsize = DWLineGen( linedelta, addrdelta, buff );
        PutInfo( vmem_addr, buff, dwsize );
        vmem_addr += dwsize;
        lineptr = (void *)( (char *)lineptr + item_size );
    }
    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.u.vm_ptr = vmem_addr + 3;
}
Beispiel #11
0
void DwarfAddModule( mod_entry *mod, section *sect )
/**************************************************/
// this generates the headers needed in the individual sections
{
    arange_prologue     arange_hdr;
    stmt_prologue       stmt_hdr;
    compuhdr_prologue   compuhdr;
    unsigned_8          abbrev_code;
    size_t              namelen;
    char *              buff;
    unsigned_32         stmt_list;

    sect = sect;
    if( (mod->modinfo & MOD_DBI_SEEN) == 0 ) {
        if( mod->d.d->arange.size > 0 ) {
            mod->d.d->arange.u.vm_ptr = SectionTable[SECT_DEBUG_ARANGE].vm_ptr + mod->d.d->arange.u.vm_offs;
            arange_hdr.length = mod->d.d->arange.size - sizeof( unsigned_32 );
            arange_hdr.version = 2;
            arange_hdr.debug_offset = mod->d.d->pubsym.u.vm_offs + SectionTable[SECT_DEBUG_INFO].start;
            arange_hdr.offset_size = sizeof( offset );
            if( FmtData.type & MK_SEGMENTED ) {
                arange_hdr.segment_size = sizeof( segment );
            } else {
                arange_hdr.segment_size = 0;
            }
//          memset( arange_hdr.padding, 0, sizeof( arange_hdr.padding ) );
            PutInfo( mod->d.d->arange.u.vm_ptr, (void *)&arange_hdr, sizeof( arange_prologue ) );
            mod->d.d->arange.u.vm_ptr += sizeof( arange_prologue );
        }
        mod->d.d->pubsym.u.vm_ptr = SectionTable[SECT_DEBUG_INFO].vm_ptr + mod->d.d->pubsym.u.vm_offs;
        compuhdr.length = mod->d.d->pubsym.size - sizeof( unsigned_32 );
        compuhdr.version = 2;
        compuhdr.abbrev_offset = SectionTable[SECT_DEBUG_ABBREV].start;
        compuhdr.addr_size = sizeof( offset );
        PutInfo( mod->d.d->pubsym.u.vm_ptr, (void *)&compuhdr, sizeof( compuhdr ) );
        mod->d.d->pubsym.u.vm_ptr += sizeof( compuhdr );
        /* output abbrev code */
        if( mod->d.d->dasi.size > 0 ) {
            abbrev_code = COMPUNIT_ABBREV_CODE;
        } else {
            abbrev_code = CU_NOLINE_ABBREV_CODE;
        }
        PutInfo( mod->d.d->pubsym.u.vm_ptr, &abbrev_code, sizeof( abbrev_code ) );
        mod->d.d->pubsym.u.vm_ptr += sizeof( abbrev_code );
        /* output module name */
        namelen = strlen( mod->name ) + 1;
        PutInfo( mod->d.d->pubsym.u.vm_ptr, mod->name, namelen );
        mod->d.d->pubsym.u.vm_ptr += namelen;
        /* output producer */
        PutInfo( mod->d.d->pubsym.u.vm_ptr, WLINK_PRODUCER, sizeof( WLINK_PRODUCER ) );
        mod->d.d->pubsym.u.vm_ptr += sizeof( WLINK_PRODUCER );
        if( mod->d.d->dasi.size > 0 ) {
            /* output stmts offset */
            stmt_list = mod->d.d->dasi.u.vm_offs + SectionTable[SECT_DEBUG_LINE].start;
            PutInfo( mod->d.d->pubsym.u.vm_ptr, &stmt_list, sizeof( unsigned_32 ) );
            mod->d.d->pubsym.u.vm_ptr += sizeof( unsigned_32 );
            /* output stmts header */
            mod->d.d->dasi.u.vm_ptr = SectionTable[SECT_DEBUG_LINE].vm_ptr + mod->d.d->dasi.u.vm_offs;
            stmt_hdr.total_length = mod->d.d->dasi.size - sizeof( unsigned_32 );
            stmt_hdr.version = 2;
            stmt_hdr.prologue_length = GetStmtHeaderSize( mod ) - offsetof( stmt_prologue, minimum_instruction_length );
            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.u.vm_ptr, (void *)&stmt_hdr, sizeof( stmt_prologue ) );
            mod->d.d->dasi.u.vm_ptr += sizeof( stmt_prologue );
            PutInfoNulls( mod->d.d->dasi.u.vm_ptr, 1 );  // no include directories;
            mod->d.d->dasi.u.vm_ptr += 1;
            buff = alloca( namelen + 3 );
            memcpy( &buff[0], mod->name, namelen );
            buff[namelen + 0] = 0;          // no directory index
            buff[namelen + 1] = 0;          // no time
            buff[namelen + 2] = 0;          // no length
            PutInfo( mod->d.d->dasi.u.vm_ptr, buff, namelen + 3 );
            mod->d.d->dasi.u.vm_ptr += namelen + 3;
            PutInfoNulls( mod->d.d->dasi.u.vm_ptr, 1 );  // no more file names
            mod->d.d->dasi.u.vm_ptr += 1;
        }
    }
}
Beispiel #12
0
static void DumpInfo( sect_number sect, void *data, unsigned len )
/****************************************************************/
{
    PutInfo( SectAddrs[sect].u.vm_ptr, data, len );
    SectAddrs[sect].u.vm_ptr += len;
}