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