Exemple #1
0
target_offset_t SegmentAlignment(   // SEGMENT: ALIGNMENT FOR SYMBOL
    SYMBOL sym )                    // - symbol to align
{
    target_offset_t align;
    TYPE type;
    TYPE align_type;

    if( CompFlags.dont_align_segs ) {
        return( TARGET_CHAR );
    }
#if _CPU == _AXP
    if( PackAmount != TARGET_CHAR ) {
#else
    if( OptSize <= 50 || PackAmount != TARGET_CHAR ) {
#endif
        type = sym->sym_type;
        align_type = AlignmentType( type );
        align = segmentTypeSize( align_type );
        if( align == TARGET_CHAR ) {
            // no alignment; let PackAlignment know the real size
            align = segmentTypeSize( type );
        }
        align = PackAlignment( TARGET_MAX_PACKING, align );
    } else {
        align = TARGET_CHAR;
    }
    return( align );
}


target_offset_t SegmentAdjust(  // SEGMENT: ADJUST OFFSET TO ALIGN
    fe_seg_id segid,            // - segment identifier
    target_size_t offset,       // - current offset
    target_offset_t align )     // - required aligment
{
    target_size_t   calc_offset;
    target_offset_t adjust;

    switch( segid ) {
    case SEG_INIT_BEG:
    case SEG_INIT_REF:
    case SEG_INIT_END:
    case SEG_FINI_BEG:
    case SEG_FINI_REF:
    case SEG_FINI_END:
        /* no padding in these segments */
        return( 0 );
    }
    calc_offset = offset;
    calc_offset += align - 1;
    calc_offset &= ~(((target_size_t) align ) - 1 );
    adjust = calc_offset - offset;
    _CHECK_ADJUST( adjust, calc_offset, offset );
    return( adjust );
}
Exemple #2
0
static bool same_segment(   // DETERMINE IF SAME SEGMENT
    void * _curr,           // - current segment
    const void * _lk )      // - segment lookup structure
{
    PC_SEGMENT *curr = _curr;
    const struct seg_look* lk = _lk;

    target_offset_t     align_adjust;
    target_size_t       new_offset;

    if( lk->use_seg_id && lk->seg_id != SEG_NULL && curr->seg_id != lk->seg_id ) {
        return( FALSE );
    }
    if( lk->use_attrs && curr->attrs != lk->attrs ) {
        return( FALSE );
    }
    if( lk->use_align && curr->align != lk->align ) {
        return( FALSE );
    }
    if( lk->use_sym_size_align ) {
        align_adjust = SegmentAdjust( curr->seg_id, curr->offset, lk->sym_align );
        new_offset = curr->offset + align_adjust + lk->sym_size;
        if( _CHECK_ADJUST( new_offset, curr->offset ) ) {
            new_offset = 0;
        }
        if( new_offset == 0 ) {
            return( FALSE );
        }
    }
    if( lk->use_name ) {
        if( strcmp( curr->name, lk->seg_name ) != 0 ) {
            return( FALSE );
        }
        if( curr->class_name != NULL ) {
            if( lk->class_name == NULL ) {
                return( FALSE );
            }
            if( strcmp( curr->class_name, lk->class_name ) != 0 ) {
                return( FALSE );
            }
        } else {
            if( lk->class_name != NULL ) {
                return( FALSE );
            }
        }
    }
    if( lk->use_only_strings && !curr->only_strings ) {
        return( FALSE );
    }
    return( TRUE );
}
Exemple #3
0
fe_seg_id SegmentAddSym(        // SEGMENT: ADD SYMBOL TO SPECIFIED SEGMENT
    SYMBOL sym,                 // - sym to add
    fe_seg_id id,               // - id of segment to use
    target_size_t size,         // - size of sym
    target_offset_t align )     // - alignment for sym
{
    PC_SEGMENT *curr;           // - new segment
    target_size_t aligned_offset;
    target_size_t calc_offset;
    target_size_t total_size;

    if( id == SEG_DATA || ( id == SEG_BSS && flags.use_def_seg ) ) {
        curr = data_def_seg.pcseg;
        id = curr->seg_id;
    } else if( id == SEG_CODE ) {
        curr = code_def_seg.pcseg;
        id = curr->seg_id;
    } else {
        curr = segIdLookup( id );
    }
    if( curr == NULL ) {
        CFatal( "segment: cannot find default segment" );
    } else {
        accumAlignment( curr, align );
        if( ( ! SymIsInitialized( sym ) ) && SymIsExtern( sym ) ) {
            id = curr->seg_id;
            _markUsed( curr, TRUE );
            curr->has_data = TRUE;
            data_def_seg.ds_used = TRUE;
        } else {
            aligned_offset = SegmentAdjust( curr->seg_id, curr->offset, align );
            calc_offset = curr->offset + aligned_offset + size;
            _CHECK_ADJUST( calc_offset, calc_offset, curr->offset );
            if( calc_offset == 0 ) {
                if( size != 0 ) {
                    CErr( ERR_MAX_SEGMENT_EXCEEDED, curr->name, sym );
                }
                id = SEG_NULL;
            } else if( curr->dgroup ) {
                total_size = dgroup_size + size + aligned_offset;
                _CHECK_ADJUST( calc_offset, total_size, dgroup_size );
                if( calc_offset == 0 ) {
                    if( size != 0 ) {
                        CErr( ERR_MAX_DGROUP_EXCEEDED, sym, curr->name );
                    }
                    id = SEG_NULL;
                } else {
                    dgroup_size += size + aligned_offset;
                    curr->offset = calc_offset;
                    _markUsed( curr, TRUE );
                    curr->has_data = TRUE;
                    id = curr->seg_id;
                    data_def_seg.ds_used = TRUE;
                }
            } else {
                curr->offset = calc_offset;
                _markUsed( curr, TRUE );
                curr->has_data = TRUE;
                id = curr->seg_id;
                data_def_seg.ds_used = TRUE;
            }
        }
    }
    return id;
}