implib.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,023 行 · 第 1/3 页
C
1,023 行
LibSeek( io, 0x00, SEEK_SET );
if( Options.libtype == WL_TYPE_MLIB ) {
FatalError( ERR_NOT_LIB, "COFF", LibFormat() );
}
if( Options.coff_found || (Options.libtype == WL_TYPE_AR && !Options.omf_found) ) {
coff_obj = TRUE;
} else {
coff_obj = FALSE;
}
file = OpenObjFile( io->name );
if( !file->orl ) {
FatalError( ERR_CANT_READ, io->name, "Unknown error" );
}
switch( ORLFileGetMachineType( file->orl ) ) {
case ORL_MACHINE_TYPE_ALPHA:
processor = WL_PROC_AXP;
coff_obj = TRUE;
Options.coff_found = TRUE;
break;
case ORL_MACHINE_TYPE_PPC601:
processor = WL_PROC_PPC;
Options.coff_found = TRUE;
coff_obj = TRUE;
break;
case ORL_MACHINE_TYPE_I386:
processor = WL_PROC_X86;
break;
case ORL_MACHINE_TYPE_NONE:
break;
default:
FatalError( ERR_CANT_READ, io->name, "Not an AXP or PPC DLL" );
}
export_sec = FindSec( file, ".edata" );
ORLSecGetContents( export_sec, &edata );
export_base = ORLSecGetBase( export_sec );
if( export_table_rva != 0 ) {
adjust = export_base - export_table_rva;
edata += export_table_rva - export_base;
} else {
adjust = 0;
}
export_header = (Coff32_Export *)edata;
name_table = (Coff32_EName *)(edata + export_header->NamePointerTableRVA -
export_base + adjust);
ord_table = (Coff32_EOrd *)(edata + export_header->OrdTableRVA -
export_base + adjust);
ordinal_base = export_header->ordBase;
DLLName = edata + export_header->nameRVA - export_base + adjust;
oldname = arch->name;
arch->name = DLLName;
arch->ffname = NULL;
DLLName = DupStr( DLLName );
if( coff_obj == TRUE ) {
if( DLLName[ strlen(DLLName)-4 ] == '.' ) {
DLLName[ strlen(DLLName)-4 ] = '\0';
}
coffAddImportOverhead( arch, DLLName, processor );
}
for( i = 0; i < export_header->numNamePointer; i++ ) {
currname = &(edata[name_table[i] - export_base + adjust]);
// allocate the space for the current symbol name and
// add enough room for the following strcpy/strcat pairs.
buffer = MemAlloc( 1 + strlen( currname ) + 8 );
if( coff_obj == TRUE ) {
CoffMKImport( arch, ORDINAL, ord_table[ i ] + ordinal_base,
DLLName, currname, NULL, processor );
} else {
type = Options.r_ordinal ? ORDINAL : NAMED;
OmfMKImport( arch, ord_table[ i ] + ordinal_base, DLLName, currname, NULL, type );
}
AddSym( currname, SYM_STRONG, 0 );
strcpy( buffer, "__imp_" );
strcat( buffer, currname );
AddSym( buffer, SYM_WEAK, 0 );
if( processor == WL_PROC_PPC ) {
strcpy( buffer, ".." );
strcat( buffer, currname );
AddSym( buffer, SYM_WEAK, 0 );
}
MemFree( buffer ); // dispose symbol name.
}
MemFree( DLLName );
arch->name = oldname;
CloseObjFile( file );
}
static char *GetImportString( char **rawpntr, char *original )
{
int quote = FALSE;
char *raw = *rawpntr;
char *result;
if( *raw == '\'' ) {
quote = TRUE;
++raw;
}
result = raw;
while( *raw && (quote || (*raw != '.')) ) {
if( quote && (*raw == '\'') ) {
quote = FALSE;
*raw++ = 0x00;
break;
}
++raw;
} /* while */
if( *raw == '.' || (!*raw && !quote) ) {
if( *raw == '.' )
*raw++ = 0x00;
*rawpntr = raw;
} else {
FatalError( ERR_BAD_CMDLINE, original );
}
return( result );
} /* GetImportString() */
void ProcessImport( char *name )
{
char *DLLName, *symName, *exportedName, *ordString;
long ordinal = 0;
arch_header *arch;
char *buffer;
Elf32_Export export_table[2];
Elf32_Sym sym_table[3];
char *strings;
char *namecopy;
namecopy = DupStr( name );
symName = GetImportString( &name, namecopy );
if( !*name || !*symName ) {
FatalError( ERR_BAD_CMDLINE, namecopy );
}
DLLName = GetImportString( &name, namecopy );
if( !*DLLName ) {
FatalError( ERR_BAD_CMDLINE, namecopy );
}
exportedName = symName; // JBS 99/07/01 give it a default value
if( *name ) {
ordString = GetImportString( &name, namecopy );
if( *ordString ) {
if( isdigit( *ordString ) )
ordinal = strtoul( ordString, NULL, 0 );
else
symName = ordString;
}
/*
* Make sure there is nothing other than white space on the rest
* of the line.
*/
if( ordinal ) {
while( *name && isspace( *name ) )
++name;
if( *name != 0x00 ) {
FatalError( ERR_BAD_CMDLINE, namecopy );
}
} else if( *name ) {
exportedName = GetImportString( &name, namecopy );
if( !exportedName || !*exportedName ) {
exportedName = symName;
} else if( isdigit( *exportedName ) ) {
ordinal = strtoul( exportedName, NULL, 0 );
exportedName = symName;
} else if( *name ) {
ordString = GetImportString( &name, namecopy );
if( *ordString ) {
if( isdigit( *ordString ) ) {
ordinal = strtoul( ordString, NULL, 0 );
} else {
FatalError( ERR_BAD_CMDLINE, namecopy );
}
}
}
}
} /* if */
MemFree( namecopy );
arch = MemAlloc( sizeof( arch_header ) );
arch->name = DupStr( DLLName );
arch->ffname = NULL;
arch->date = time( NULL );
arch->uid = 0;
arch->gid = 0;
arch->mode = 0x100666;
arch->size = 0;
arch->fnametab = NULL;
arch->ffnametab = NULL;
if( Options.filetype == 0 ) {
if( Options.omf_found ) {
Options.filetype = WL_TYPE_OMF;
} else if( Options.coff_found ) {
Options.filetype = WL_TYPE_COFF;
} else if( Options.elf_found ) {
Options.filetype = WL_TYPE_ELF;
}
}
if( Options.processor == 0 ) {
switch( Options.filetype ) {
case WL_TYPE_OMF:
Options.processor = WL_PROC_X86;
break;
case WL_TYPE_ELF:
Options.processor = WL_PROC_PPC;
break;
default:
switch( Options.libtype ) {
case WL_TYPE_OMF:
Options.processor = WL_PROC_X86;
break;
case WL_TYPE_MLIB:
Options.processor = WL_PROC_PPC;
break;
default:
# ifdef __PPC__
Options.processor = WL_PROC_PPC;
#else
#ifdef __AXP__
Options.processor = WL_PROC_AXP;
#else
Options.processor = WL_PROC_X86;
#endif
#endif
}
}
Warning( ERR_NO_PROCESSOR, procname[Options.processor] );
}
if( Options.filetype == 0 ) {
switch( Options.libtype ) {
case WL_TYPE_MLIB:
Options.filetype = WL_TYPE_ELF;
Warning( ERR_NO_TYPE, "ELF" );
break;
case WL_TYPE_AR:
Options.filetype = WL_TYPE_COFF;
Warning( ERR_NO_TYPE, "COFF" );
break;
case WL_TYPE_OMF:
Options.filetype = WL_TYPE_OMF;
Warning( ERR_NO_TYPE, "OMF" );
break;
default:
switch( Options.processor ) {
case WL_PROC_X86:
Options.filetype = WL_TYPE_OMF;
Warning( ERR_NO_TYPE, "OMF" );
break;
case WL_PROC_AXP:
Options.libtype = WL_TYPE_AR;
Options.filetype = WL_TYPE_COFF;
Warning( ERR_NO_TYPE, "COFF" );
break;
case WL_PROC_PPC:
#ifdef __NT__
Options.libtype = WL_TYPE_AR;
Options.filetype = WL_TYPE_COFF;
Warning( ERR_NO_TYPE, "COFF" );
#else
Options.libtype = WL_TYPE_MLIB;
Options.filetype = WL_TYPE_ELF;
Warning( ERR_NO_TYPE, "ELF" );
#endif
}
}
}
if( !Options.libtype ) {
switch( Options.filetype ) {
case WL_TYPE_ELF:
Options.libtype = WL_TYPE_MLIB;
break;
case WL_TYPE_COFF:
Options.libtype = WL_TYPE_AR;
break;
}
}
switch( Options.filetype ) {
case WL_TYPE_ELF:
if( ordinal == 0 ) {
export_table[0].exp_ordinal = -1;
export_table[1].exp_ordinal = -1;
} else {
export_table[0].exp_ordinal = ordinal;
export_table[1].exp_ordinal = ordinal;
}
export_table[0].exp_symbol = 1;
export_table[1].exp_symbol = 2;
sym_table[1].st_name = 0;
sym_table[2].st_name = strlen(symName) + 1;
strings = MemAlloc( strlen(symName) + strlen( exportedName ) + 2 );
strcpy( strings, symName );
strcpy( strings + strlen(symName) + 1, exportedName );
ElfMKImport( arch, ELFRENAMED, 2, DLLName, strings,
export_table, sym_table, Options.processor );
MemFree( strings );
break;
case WL_TYPE_COFF:
if( Options.libtype != WL_TYPE_AR ) {
FatalError( ERR_NOT_LIB, "COFF", LibFormat() );
}
coffAddImportOverhead( arch, DLLName, Options.processor );
if( ordinal == 0 ) {
CoffMKImport( arch, NAMED, ordinal, DLLName, symName,
exportedName, Options.processor );
} else {
CoffMKImport( arch, ORDINAL, ordinal, DLLName, symName, // JBS 99/07/01
NULL, Options.processor );
}
buffer = MemAlloc( strlen( exportedName ) + 7 );
strcpy( buffer, "__imp_" );
strcat( buffer, exportedName );
AddSym( buffer, SYM_WEAK, 0 );
if( Options.processor == WL_PROC_PPC ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?