novlldr.c

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

C
937
字号
            ret_list = rt->ret_list;
            FreeSeg( FP_SEG( rt ), 1, __WhichArea__( FP_SEG( rt ) ) );
            /* Since we have left the FLAG_RET_TRAP set we don't have to
               worry about ForceAllocate trying to remove this section
               from memory.  i.e., we still may have the trap on the
               stack; so we don't want any of our routines to try to
               move it or throw it out :> */
        } else {
            stack_trap = 0;
#endif
        }
        segment = ForceAllocate( ovl->num_paras );
#ifdef OVL_MULTITHREAD
        if( ovl->flags_anc & FLAG_RET_TRAP ) {
            rt_seg = ovl->code_handle;
            FreeSeg( rt_seg, RET_TRAP_PARA, __WhichArea__( rt_seg ) );
            ovl->flags_anc &= ~(FLAG_RET_TRAP|FLAG_ACTIVE_TRAP);
            __OVLUNDORETTRAP__( rt_seg, segment );
            OVL_ACCESSES( ovl ) = 1; /* this overlay has been accessed */
        }
#else
        if( stack_trap != 0 ) {
            ovl->flags_anc &= ~FLAG_RET_TRAP;
            __OVLUNDORETTRAP__( stack_trap, ret_offset, ret_list, segment );
            OVL_ACCESSES( ovl ) = 1; /* this overlay has been accessed */
        }
#endif
        ovl->code_handle = segment;
        *(desc_ptr)MK_FP( segment - 1, 0xE ) = ovl_num;
        ovl->flags_anc |= FLAG_CHANGED;
        ovl->start_para = __OVLSTARTPARA__; /* restore start_para */
        __LoadSectionCode__( ovl );
        ovl->start_para = 0;
#ifdef OVL_DEBUG
        __OvlMsg__( OVL_SECTION );
        __OvlNum__( ovl_num );
        __OvlMsg__( OVL_LOADED );
#endif
    } else {
        OVL_ACCESSES( ovl ) = 1; /* this overlay has been accessed */
        segment = ovl->code_handle;
#ifdef OVL_DEBUG
        __OvlMsg__( OVL_SECTION );
        __OvlNum__( ovl_num );
        __OvlMsg__( OVL_RESIDENT );
#endif
    }
    return( segment );
}


unsigned near __WOVLLDR__( lvector_ptr vect )
/******************************************/
// Load overlay.
{
    unsigned        retval;
    unsigned        ovl_num;

    ovl_num = vect->u.v.sec_num;            // get the overlay number
    retval = __LoadNewOverlay__( ovl_num );     // load the overlay
    vect->target.seg += retval;                 // now munge the vector.
    vect->u.i.tab_addr = FP_OFF( &__OVLTAB__.entries[ ovl_num - 1] );
    vect->u.i.cs_over = OVV_CS_OVERRIDE;
    vect->u.i.inc_op = OVV_INC_OPCODE;
    __NDBG_HOOK__( ovl_num, 0, __OVLCAUSE__ );
    return( retval );
}


void near __OVLINITAREA__( unsigned start, unsigned size )
/*********************************************************/
/* initialize an overlay area */
{
    area_list_ptr       area;
    free_block_ptr      freelist;

    area = MK_FP( start, 0 );
    area->fblk.next = start + 1;
    area->fblk.prev = start + size - 1;
    area->fblk.num_paras = 0;
    area->next = NULL_SEG;
    area->size = size;
    area->free_paras = size - 2;
    /* construct initial free list */
    freelist = MK_FP( start + 1, 0 );
    freelist->prev = start;
    freelist->next = start + size - 1;
    freelist->num_paras = size - 2;
    /* construct dummy blk at end of list */
    freelist = MK_FP( start + size - 1, 0 );
    freelist->prev = start + 1;
    freelist->next = start;
    freelist->num_paras = 0;
}


dos_addr near __NOVLTINIT__( void )
/*********************************/
// Overlay initialization.
{
    ovltab_entry_ptr    ovl;
#ifdef OVL_DEBUG
    unsigned int        ovl_num = 1;
#endif

    if( __OVLTAB__.prolog.major != OVL_MAJOR_VERSION
        || __OVLTAB__.prolog.minor > OVL_MINOR_VERSION ) {
        __OvlExit__( OVL_BAD_VERSION );
    }
    __OVLFILEPREV__ = 0xFFFF;
    ovl = __OVLTAB__.entries;
    /* We assume that the first overlay table entry is NOT a PRELOAD-type
     * overlay... thus its start_para is the start_para of all the dynamic
     * sections. */
    __OVLSTARTPARA__ = ovl->start_para; /* save for later */
    __OVLAREALIST__ = __OVLTAB__.prolog.delta + ovl->start_para;
    __OVLROVER__ = 1;

    while( FP_OFF( ovl ) < FP_OFF( &__OVLTABEND__ ) ) {
        if( ovl->flags_anc & OVE_FLAG_PRELOAD ) {
            ovl->code_handle = ovl->start_para + __OVLTAB__.prolog.delta;
#ifdef OVL_DEBUG
            __OvlMsg__( OVL_SECTION );
            __OvlNum__( ovl_num );
            __OvlMsg__( OVL_LOADED );
#endif
            __LoadSectionCode__( ovl );
            ovl->num_paras = 0;     /* don't count in in largest size calcs*/
        }
 /* set default flags to zero, set reference count to zero, and make sure that
  * preload sections aren't unloaded (because FLAG_IN_MEM is not set)
  * (all in one statement!) */
        ovl->flags_anc = 0;
        ovl->start_para = 0;    /* required by ForceAllocate code */
        ovl->code_handle = 0;   /* required by debugging support */
#ifdef OVL_DEBUG
        ovl_num++;
#endif
        ovl++;
    }
    return( __OVLTAB__.prolog.start );
}


/* these two routines are for the C setjmp/longjmp support */

extern unsigned long far __FINDOVLADDR__( unsigned unused, unsigned segment )
/***************************************************************************/
/* find the overlay number corresponding to the given segment, and turn the
 * segment into a relative offset from the beginning of the section */
{
    unsigned            ovl_num;

    unused = unused;    /* to prevent a warning - will be optimized away */
    if( segment < __OVLTAB__.prolog.delta + __OVLSTARTPARA__ ) {
        ovl_num = 0;  /* in the root */
    } else {
        ovl_num = *(desc_ptr)MK_FP( segment - 1, 0xE ); /* in overlay */
    }
    return( ( (unsigned_32)segment << 16 ) | ovl_num );
}


#ifdef OVL_MULTITHREAD
extern unsigned_32 near __OVLLONGJMP__( unsigned ovl_num, unsigned segment )
#else
extern unsigned_32 near __OVLLONGJMP__( unsigned ovl_num, unsigned segment,
                                                            unsigned bp_chain )
#endif
/*****************************************************************************/
/* Ensure that ovl_num is loaded into memory.  Return the segment of ovl_num
 * in DX.  Check all return traps; and move them to higher stack locations
 * if required. This function is wrapped by longjmp_wrap in novlmain.asm */
{
    ovltab_entry_ptr    ovl;
#ifdef OVL_MULTITHREAD
    unsigned_16         rt_seg;
#else
    ret_trap_ptr        rt;
#endif

    /* check return traps */
    for( ovl = &__OVLTAB__.entries[ 0 ];
            FP_OFF( ovl ) < FP_OFF( &__OVLTABEND__ ); ++ovl ) {
        if( (ovl->flags_anc & FLAG_RET_TRAP) == 0 )
            continue;
#ifdef OVL_MULTITHREAD
        rt_seg = ovl->code_handle;
#else
        rt = MK_FP( ovl->code_handle, 0 );
        if( rt->stack_trap >= bp_chain )
            continue; /* trap safe */
        if( rt->ret_list < bp_chain ) {
            ovl->flags_anc &= ~FLAG_RET_TRAP;
            FreeSeg( FP_SEG( rt ), 1, __WhichArea__( FP_SEG( rt ) ) );
            continue;  /* trap removed */
        }
#endif
        /*
            __OVLUNDORETTRAP__ only undoes things down to the head of the bp
            chain.  We know from above conditions that there must be
            at least one occurance above the bp_chain head.  This could
            be faster; but it gets more complicated.
        */
#ifdef OVL_MULTITHREAD
        if( __OVLUNDORETTRAP__( rt_seg, rt_seg ) == 0 ) {
            ovl->flags_anc &= ~FLAG_RET_TRAP;
            FreeSeg( rt_seg, RET_TRAP_PARA, __WhichArea__( rt_seg ) );
            /* trap removed */
        } else {
            __OVLBUILDRETTRAP__( rt_seg, rt_seg );
        }
#else
        __OVLUNDORETTRAP__( rt->stack_trap, 0, rt->ret_list, FP_SEG( rt ) );
        __OVLBUILDRETTRAP__( FP_SEG( rt ), FP_SEG( rt ) );
#endif
    }
    if( ovl_num == 0 )
        return( (unsigned_32)segment << 16 );
    segment = __LoadNewOverlay__( ovl_num );
    return( (unsigned_32)segment << 16 );
}


#ifdef OVL_DEBUG
#include <conio.h>

#pragma aux cprintf modify [es ds];

#define CRLF "\r\n"

extern void far __NOVLDUMP__( void )
/**********************************/
{
    ovltab_entry_ptr    ovl;
    unsigned            ovl_num;
    unsigned_16         fn_off;

    cprintf( "ovltab_prolog" CRLF );
    cprintf( "  major=%u, minor=%u, start=%04xh:%04xh," CRLF,
        __OVLTAB__.prolog.major, __OVLTAB__.prolog.minor,
        __OVLTAB__.prolog.start.seg, __OVLTAB__.prolog.start.off );
    cprintf( "  delta=%04xh, ovl_size=%04xh" CRLF CRLF, __OVLTAB__.prolog.delta,
        __OVLTAB__.prolog.ovl_size );

    ovl = &__OVLTAB__.entries[ 0 ];
    ovl_num = 1;
    while( FP_OFF( ovl ) < FP_OFF( &__OVLTABEND__ ) ) {
        cprintf( "overlay %u:" CRLF "  flags_anc=%04xh", ovl_num,
            ovl->flags_anc );
        if( ovl->flags_anc & FLAG_CHANGED ) {
            cprintf( " FLAG_CHANGED" );
        }
        if( ovl->flags_anc & FLAG_INMEM ) {
            cprintf( " FLAG_INMEM" );
        }
        if( ovl->flags_anc & FLAG_SELF_REF ) {
            cprintf( " FLAG_SELF_REF" );
        }
        if( ovl->flags_anc & FLAG_RET_TRAP ) {
            cprintf( " FLAG_RET_TRAP" );
        }
        cprintf( CRLF "  relocs=%04xh, start_para=%04xh, code_handle=%04xh"CRLF,
            ovl->relocs, ovl->start_para, ovl->code_handle );
        fn_off = ovl->fname & ~OVE_EXE_FILENAME;
        cprintf( "  num_paras=%04xh, fname=%04xh(%s), disk_addr=%08lxh" CRLF,
            ovl->num_paras, ovl->fname, (char far *)&__OVLTAB__ + fn_off,
            ovl->disk_addr );
        if( ovl->flags_anc & FLAG_RET_TRAP ) {
            ret_trap_ptr        rt;
            unsigned_16         ret;
            unsigned_16 far     *stk_ptr;
#ifdef OVL_MULTITHREAD
            int                 i;
#endif

            rt = MK_FP( ovl->code_handle, 0 );
            cprintf( "  return trap:" CRLF );
#ifdef OVL_MULTITHREAD
            for( i = 0; rt->traps[i].stack_trap != 0; ++i ) {
                cprintf( "  Thread=%d", i );
                cprintf( "    ret_offset=%04xh, stack_trap=%04xh" CRLF,
                    rt->traps[i].ret_offset, rt->traps[i].stack_trap );
                cprintf( "    ret_list=%04xh", rt->traps[i].ret_list );
                ret = rt->traps[i].ret_list;
                while( ret != 0 ) {
                    stk_ptr = MK_FP( FP_SEG( &stk_ptr ), ret+4 );
                    ret = *stk_ptr;
                    cprintf( ", %04xh", ret );
                }
            }
#else
            cprintf( "    ret_offset=%04xh, stack_trap=%04xh" CRLF,
                rt->ret_offset, rt->stack_trap );
            cprintf( "    ret_list=%04xh", rt->ret_list );
            ret = rt->ret_list;
            while( ret != 0 ) {
                stk_ptr = MK_FP( FP_SEG( &stk_ptr ), ret+4 );
                ret = *stk_ptr;
                cprintf( ", %04xh", ret );
            }
#endif
            cprintf( CRLF );
        }
        cprintf( CRLF );
        ++ovl;
        ++ovl_num;
    }
}
#endif

⌨️ 快捷键说明

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