impexp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 555 行 · 第 1/2 页
C
555 行
DbgAssert(name[0] == '.' && name[1] == '.');
name += 2; // skip '..' at the beginning of the name
}
prefixlen = sizeof(ImportSymPrefix) - 1;
namelen = strlen( name );
iatname = alloca( namelen + prefixlen + 1 );
memcpy( iatname, ImportSymPrefix, prefixlen );
memcpy( iatname + prefixlen, name, namelen );
prefixlen += namelen;
iatname[prefixlen] = '\0';
return SymOp( ST_CREATE, iatname, prefixlen );
}
extern void MSImportKeyword( symbol *sym, length_name *modname,
length_name *extname, unsigned long ordinal )
/************************************************************************/
/* process the MS import keyword definition */
{
dll_sym_info * dll;
if( !(sym->info & SYM_DEFINED) ) {
sym->info |= SYM_DEFINED | SYM_DCE_REF;
if( LinkFlags & STRIP_CODE ) {
DefStripImpSym(sym);
}
SET_SYM_TYPE( sym, SYM_IMPORTED );
dll = AllocDLLInfo();
sym->p.import = dll;
if( FmtData.type & MK_PE ) {
dll->iatsym = GetIATSym( sym );
dll->iatsym->info |= SYM_DEFINED | SYM_DCE_REF;
SET_SYM_TYPE( dll->iatsym, SYM_IMPORTED );
dll->iatsym->p.import = NULL;
}
dll->m.modnum = AddNameTable( modname->name, modname->len, TRUE,
&FmtData.u.os2.mod_ref_list );
dll->isordinal = ordinal != NOT_IMP_BY_ORDINAL;
if( !dll->isordinal ) {
dll->u.entry = AddNameTable( extname->name, extname->len, FALSE,
&FmtData.u.os2.imp_tab_list );
} else {
dll->u.ordinal = ordinal;
}
}
}
extern void KillDependantSyms( symbol *sym )
/******************************************/
{
if( !(FmtData.type & MK_PE) ) return;
sym = GetIATSym( sym );
sym->info |= SYM_KILL;
}
extern void AssignOrdinals( void )
/********************************/
/* assign ordinal values to entries in the export list */
{
entry_export * exp;
entry_export * place;
entry_export * prev;
bool isspace;
if( FmtData.u.os2.exports != NULL ) {
if( FmtData.u.os2.old_lib_name != NULL ) {
ReadOldLib();
}
exp = prev = FmtData.u.os2.exports;
place = prev->next;
while( exp->ordinal == 0 ) { // while still unassigned values
for(;;) { // search for an unassigned value
if( place != NULL ) {
isspace = (place->ordinal - prev->ordinal > 1);
}
if( place == NULL || isspace ) {
if( FmtData.u.os2.exports != prev ) {
FmtData.u.os2.exports = exp->next;
prev->next = exp;
exp->next = place;
}
exp->ordinal = prev->ordinal + 1;
prev = exp; // now exp is 'previous' to place
break;
} else {
prev = place;
place = place->next;
}
}
exp = FmtData.u.os2.exports;
}
}
}
static void ReadOldLib( void )
/****************************/
// Read an old DLL & match ordinals of exports in it with exports in this.
{
f_handle the_file;
long filepos;
union {
dos_exe_header dos;
os2_exe_header os2;
os2_flat_header os2f;
pe_header pe;
} head;
char * fname;
pe_object * objects;
pe_object * currobj;
fname = FmtData.u.os2.old_lib_name;
the_file = QOpenR( fname );
QRead( the_file, &head, sizeof(dos_exe_header), fname );
if( head.dos.signature != 0x5A4D || head.dos.reloc_offset != 0x40 ) {
LnkMsg( WRN + MSG_INV_OLD_DLL, NULL );
} else {
QSeek( the_file, 0x3c, fname );
QRead( the_file, &filepos, sizeof( long ), fname );
QSeek( the_file, filepos, fname );
QRead( the_file, &head, sizeof(head), fname );
if( head.os2.signature == OS2_SIGNATURE_WORD ) {
QSeek( the_file, filepos + head.os2.resident_off, fname );
ReadNameTable( the_file );
QSeek( the_file, head.os2.nonres_off, fname );
ReadNameTable( the_file );
} else if( head.os2f.signature == OSF_FLAT_SIGNATURE
|| head.os2f.signature == OSF_FLAT_LX_SIGNATURE ) {
if( head.os2f.resname_off != 0 ) {
QSeek( the_file, filepos + head.os2f.resname_off, fname );
ReadNameTable( the_file );
}
if( head.os2f.nonres_off != 0 ) {
QSeek( the_file, head.os2f.nonres_off, fname );
ReadNameTable( the_file );
}
} else if( head.pe.signature == PE_SIGNATURE ) {
_ChkAlloc( objects, head.pe.num_objects * sizeof(pe_object) );
QRead( the_file, objects, head.pe.num_objects * sizeof(pe_object),
fname );
currobj = objects;
while( head.pe.num_objects > 0 ) {
if( currobj->rva == head.pe.table[PE_TBL_EXPORT].rva ) {
QSeek( the_file, currobj->physical_offset, fname );
head.pe.table[PE_TBL_EXPORT].rva -=currobj->physical_offset;
ReadPEExportTable( the_file, &head.pe.table[PE_TBL_EXPORT]);
break;
}
head.pe.num_objects--;
currobj++;
}
_LnkFree( objects );
if( head.pe.num_objects == 0 ) {
LnkMsg( WRN + MSG_INV_OLD_DLL, NULL );
}
} else {
LnkMsg( WRN+MSG_INV_OLD_DLL, NULL );
}
}
QClose( the_file, fname );
_LnkFree( fname );
FmtData.u.os2.old_lib_name = NULL;
}
extern void CheckExport( char * name, unsigned_16 ordinal,
int (*compare_rtn)(const char *,const char *))
/*********************************************************************/
/* check if the name is exported and hasn't been assigned a value, and if so,
* give it the specified value */
{
entry_export * place;
entry_export * prev;
DEBUG(( DBG_OLD, "Oldlib export %s ordinal %l", name, ordinal ));
prev = NULL;
place = FmtData.u.os2.exports;
while( compare_rtn( place->name, name ) != 0 ) {
prev = place;
place = place->next;
if( place == NULL ) {
break;
}
}
if( place != NULL ) {
if( place->ordinal == 0 ) {
place->ordinal = ordinal;
place = FindPlace( place );
if( place != NULL ) {
if( prev == NULL ) {
FmtData.u.os2.exports = place;
} else {
prev->next = place;
}
}
}
}
}
static void ReadNameTable( f_handle the_file )
/********************************************/
// Read a name table & set export ordinal value accordingly.
{
unsigned_8 length;
unsigned_16 ordinal;
int (*compare_rtn)(const char *,const char *);
char * fname;
fname = FmtData.u.os2.old_lib_name;
if( LinkFlags & CASE_FLAG ) {
compare_rtn = &strcmp;
} else {
compare_rtn = &stricmp;
} // skip the module name & ordinal.
for( ;; ) {
QRead( the_file, &length, sizeof( unsigned_8 ), fname );
if( length == 0 ) break;
QRead( the_file, TokBuff, length, fname );
QRead( the_file, &ordinal, sizeof( unsigned_16 ), fname );
if( ordinal == 0 ) continue;
TokBuff[ length ] = '\0';
CheckExport( TokBuff, ordinal, compare_rtn );
}
}
extern unsigned_16 FindEntryOrdinal( targ_addr addr, group_entry *grp )
/*********************************************************************/
{
unsigned_16 max_ord;
entry_export ** owner;
entry_export * exp;
max_ord = 0;
owner = &FmtData.u.os2.exports;
for( ;; ) {
exp = *owner;
if( exp == NULL ) break;
if( addr.seg == exp->addr.seg && addr.off == exp->addr.off ) {
return( exp->ordinal );
}
if( exp->ordinal >= max_ord ) max_ord = exp->ordinal;
owner = &exp->next;
}
exp = AllocExport( NULL, 0 );
exp->sym = NULL;
exp->isexported = FALSE;
exp->isanonymous = FALSE;
exp->ordinal = max_ord + 1;
exp->ismovable = (grp->segflags & SEG_MOVABLE) != 0;
exp->next = NULL;
exp->addr = addr;
*owner = exp;
return( exp->ordinal );
}
extern char * ImpModuleName( dll_sym_info *dll )
/**********************************************/
{
return dll->m.modnum->name;
}
extern bool IsSymElfImported( symbol *s )
/***************************************/
{
return IS_SYM_IMPORTED(s);
}
extern bool IsSymElfExported( symbol *s )
/***************************************/
{
return FmtData.u.elf.exportallsyms || (s->info & SYM_EXPORTED);
}
extern bool IsSymElfImpExp( symbol *s )
/*************************************/
{
return IsSymElfImported(s) || IsSymElfExported(s);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?