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 + -
显示快捷键?