예제 #1
0
static void dw_reloc( dw_sectnum sect, dw_reloc_type reloc_type, ... )
/********************************************************************/
{
    va_list         args;
    dw_targ_addr    targ_data;
    dw_targ_seg     seg_data;
    uint_32         u32_data;
    dw_sectnum      sect_no;
    SYMPTR          sym;

    va_start( args, reloc_type );
    switch( reloc_type ) {
    case DW_W_LABEL:
    case DW_W_DEFAULT_FUNCTION:
    case DW_W_ARANGE_ADDR:
    case DW_W_LOW_PC:
        u32_data = 0;   // NOTE: assumes little-endian byte order
        dw_write( sect, &u32_data, TARGET_NEAR_POINTER );
        break;
    case DW_W_HIGH_PC:
        u32_data = 1;   // NOTE: assumes little-endian byte order
        dw_write( sect, &u32_data, TARGET_NEAR_POINTER );
        break;
    case DW_W_UNIT_SIZE:
        u32_data = 1;
        dw_write( sect, &u32_data, sizeof( u32_data ) );
        break;
    case DW_W_STATIC:
        sym = va_arg( args, SYMPTR );
        targ_data = 0;
        dw_write( sect, &targ_data, sizeof( targ_data ) );
        break;
    case DW_W_SEGMENT:
        sym = va_arg( args, SYMPTR );
        seg_data = SymSegId( sym );
        dw_write( sect, &seg_data, sizeof( seg_data ) );
        break;
    case DW_W_SECTION_POS:
        sect_no = va_arg( args, dw_sectnum );
        u32_data = dw_tell( sect_no );
        dw_write( sect, &u32_data, sizeof( u32_data ) );
        break;
    default:
        break;
    }
    va_end( args );
}
예제 #2
0
void SetSegment( SYMPTR sym )
{
    segment_list        *seg;
    target_size         size;

#if _CPU == 8086
    if( (sym->mods & FLAG_FAR) && CompFlags.zc_switch_used ) {
        if( CONSTANT( sym->mods )
        || (sym->attribs.stg_class == SC_STATIC && (sym->flags & SYM_TEMP)) ) {
            sym->u.var.segid = SEG_CODE;
            return;
        }
    }
#elif _CPU == 386
    if( !CompFlags.rent ) {
        if( (sym->mods & FLAG_FAR) || (TargetSwitches & FLAT_MODEL) ) {
           if( CONSTANT( sym->mods ) && CompFlags.zc_switch_used ) {
                sym->u.var.segid = SEG_CODE;
                return;
           }
           if( (sym->attribs.stg_class == SC_STATIC) && (sym->flags & SYM_TEMP) ) {
                sym->u.var.segid = SEG_CODE;
                return;
            }
         }
     }
#endif
    if( sym->mods & ( FLAG_FAR | FLAG_HUGE ) ) {
        size = SizeOfArg( sym->sym_type );
        seg = NULL;
#if _CPU == 8086
        if( size < 0x10000 ) {
            for( seg = SegListHead; seg != NULL; seg = seg->next_segment ) {
                if( seg->size_left >= size ) {
                    break;
                }
            }
        }
#else
        seg = SegListHead;
#endif
        if( seg == NULL ) {
            if( SegListHead == NULL ) {
                SegListHead = CMemAlloc( sizeof( segment_list ) );
                seg = SegListHead;
            } else {
                for( seg = SegListHead; seg->next_segment; ) {
                    seg = seg->next_segment;
                }
                seg->next_segment = CMemAlloc( sizeof( segment_list ) );
                seg = seg->next_segment;
            }
            seg->segid = SegmentNum++;
#if _CPU == 8086
            if( size > 0xFFFF ) {
                while( size > 0x0FFFF ) {       /* while >= 64K */
                    ++SegmentNum;
                    size -= 0x10000;
                }
                seg->size_left = 0;
            } else {
                seg->size_left = 0x10000 - size;
            }
#endif
        } else {
            seg->size_left -= size;
        }
        sym->u.var.segid = seg->segid;
    } else {
        sym->u.var.segid = SymSegId( sym );
    }
}