⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cofflwlv.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  COFF symbol table and relocations processing.
*
****************************************************************************/


#include "cofflwlv.h"
#include "orlhash.h"
#include "walloca.h"
#ifdef _BSD_SOURCE
#define stricmp strcasecmp
#endif

orl_return CoffCreateSymbolHandles( coff_file_handle file_hnd )
{
    int                 loop;
    int                 prev;
    int                 len;
    uint_16             type; // type of CoffSymEnt
    coff_symbol_handle  current;
    coff_sym_section *  aux;
    coff_sym_weak *     weak;
    coff_sec_handle     sechdl;

    if( file_hnd->num_symbols == 0 ){
        file_hnd->symbol_handles = NULL;
        return( ORL_OKAY );
    }
    file_hnd->symbol_handles = (coff_symbol_handle) _ClientAlloc( file_hnd, sizeof( coff_symbol_handle_struct ) * file_hnd->num_symbols );
    if( !(file_hnd->symbol_handles) ) return( ORL_OUT_OF_MEMORY );
    prev = 0;
    for( loop = 0; loop < file_hnd->num_symbols; loop++ ) {
        current = &(file_hnd->symbol_handles[loop]);
        current->file_format = ORL_COFF;
        current->coff_file_hnd = file_hnd;
        current->symbol = (coff_symbol *) &(file_hnd->symbol_table->contents[sizeof( coff_symbol ) * loop]);
        if( current->symbol->name.non_name.zeros == 0 ) {
            current->name = file_hnd->string_table->contents + current->symbol->name.non_name.offset - sizeof( coff_sec_size );
            current->name_alloced = COFF_FALSE;
        } else {
            len = strlen( current->symbol->name.name_string );
            if( strlen( current->symbol->name.name_string ) >= COFF_SYM_NAME_LEN ) {
                current->name = _ClientAlloc( file_hnd, COFF_SYM_NAME_LEN + 1 );
                strncpy( current->name, current->symbol->name.name_string, COFF_SYM_NAME_LEN );
                current->name[COFF_SYM_NAME_LEN] = '\0';
                current->name_alloced = COFF_TRUE;
            } else {
                current->name = current->symbol->name.name_string;
                current->name_alloced = COFF_FALSE;
            }
        }
        if( memcmp( current->name, ".bf", 4 ) == 0 ) {
            if( current->symbol->num_aux >= 1 ) {
                file_hnd->symbol_handles[prev].has_bf = COFF_TRUE;
            }
        }
        sechdl = NULL;
        current->type = 0;
        switch( current->symbol->sec_num ) {
            case IMAGE_SYM_DEBUG:
                current->type |= ORL_SYM_TYPE_DEBUG;
                current->binding = ORL_SYM_BINDING_NONE;
                break;
            case IMAGE_SYM_ABSOLUTE:
                current->type |= ORL_SYM_TYPE_ABSOLUTE;
                current->binding = ORL_SYM_BINDING_NONE; // ?
                break;
            case IMAGE_SYM_UNDEFINED:
                if( current->symbol->value == 0) {
                    current->type |= ORL_SYM_TYPE_UNDEFINED;
                } else {
                    current->type |= ORL_SYM_TYPE_COMMON;
                }
                break;
            default:
                current->type |= ORL_SYM_TYPE_DEFINED;
                sechdl = file_hnd->orig_sec_hnd[current->symbol->sec_num - 1];
                if( sechdl->flags & ORL_SEC_FLAG_COMDAT ) {
                    current->type |= ORL_SYM_CDAT_MASK;
                }
                break;
        }
        switch( current->symbol->storage_class ) {
            case IMAGE_SYM_CLASS_EXTERNAL:
            case IMAGE_SYM_CLASS_LABEL:
            case IMAGE_SYM_CLASS_UNDEFINED_LABEL:
            case IMAGE_SYM_CLASS_WEAK_EXTERNAL:
                if( current->symbol->storage_class
                        == IMAGE_SYM_CLASS_LABEL ) {
                    current->binding = ORL_SYM_BINDING_LOCAL;
                } else if( (current->symbol->storage_class
                                == IMAGE_SYM_CLASS_EXTERNAL
                          || current->symbol->storage_class
                                == IMAGE_SYM_CLASS_WEAK_EXTERNAL)
                        && current->symbol->sec_num == IMAGE_SYM_UNDEFINED
                        && current->symbol->value == 0
                        && current->symbol->num_aux == 1 ) {
                    weak = (coff_sym_weak *) (current->symbol + 1);
                    switch( weak->characteristics ) {
                    case IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY:
                        current->binding = ORL_SYM_BINDING_WEAK;
                        break;
                    case IMAGE_WEAK_EXTERN_SEARCH_LIBRARY:
                        current->binding = ORL_SYM_BINDING_LAZY;
                        break;
                    case IMAGE_WEAK_EXTERN_SEARCH_ALIAS:
                        current->binding = ORL_SYM_BINDING_ALIAS;
                        break;
                    }
                } else {
                    current->binding = ORL_SYM_BINDING_GLOBAL;
                }
                type = _CoffComplexType( current->symbol->type );
                if( type & IMAGE_SYM_DTYPE_FUNCTION ) {
                    current->type |= ORL_SYM_TYPE_FUNCTION;
                } else {
                    current->type |= ORL_SYM_TYPE_OBJECT;
                }
                break;
            case IMAGE_SYM_CLASS_STATIC:
                current->binding = ORL_SYM_BINDING_LOCAL;
                if( current->symbol->num_aux == 0 ) {
                    if( sechdl != NULL
                        && strcmp( sechdl->name, current->name ) == 0 ) {
                        current->type |= ORL_SYM_TYPE_SECTION;
                    } else {
                        type = _CoffComplexType( current->symbol->type );
                        if( type & IMAGE_SYM_DTYPE_FUNCTION ) {
                            current->type |= ORL_SYM_TYPE_FUNCTION;
                        } else {
                            current->type |= ORL_SYM_TYPE_OBJECT;
                        }
                    }
                } else if( current->symbol->num_aux == 1
                        && current->type & ORL_SYM_CDAT_MASK ) {
                    current->type |= ORL_SYM_TYPE_SECTION;
                    aux = (coff_sym_section *)(current->symbol + 1);
                    current->type &= ~ORL_SYM_CDAT_MASK;
                    current->type |= (aux->selection << ORL_SYM_CDAT_SHIFT)
                                        & ORL_SYM_CDAT_MASK;
                } else {
                    type = _CoffComplexType( current->symbol->type );
                    if( type & IMAGE_SYM_DTYPE_FUNCTION ) {
                        current->type |= ORL_SYM_TYPE_FUNCTION;
                    }
                }
                break;
            case IMAGE_SYM_CLASS_FUNCTION:
                // The .bf, .lf and .ef symbols are not regular symbols
                // and their values in particular must not be interpreted
                // as offsets/addresses.
                if( !memcmp( current->name, ".bf", 4 )
                    || !memcmp( current->name, ".lf", 4 )
                    || !memcmp( current->name, ".ef", 4 ) )
                    current->binding = ORL_SYM_BINDING_NONE;
                else
                    current->binding = ORL_SYM_BINDING_LOCAL;
                current->type |= ORL_SYM_TYPE_FUNC_INFO;
                break;
            case IMAGE_SYM_CLASS_FILE:
                current->binding = ORL_SYM_BINDING_LOCAL;
                current->type |= ORL_SYM_TYPE_FILE;
                break;
        }
        prev = loop;
        loop += current->symbol->num_aux;
    }
    return( ORL_OKAY );
}

orl_return CoffBuildSecNameHashTable( coff_file_handle coff_file_hnd )
{
    int                                         loop;
    orl_return                                  error;

    coff_file_hnd->sec_name_hash_table = ORLHashTableCreate( coff_file_hnd->coff_hnd->funcs, SEC_NAME_HASH_TABLE_SIZE, ORL_HASH_STRING, (orl_hash_comparison_func) stricmp );
    if( !(coff_file_hnd->sec_name_hash_table) ) {
        return( ORL_OUT_OF_MEMORY );
    }
    for( loop = 0; loop < coff_file_hnd->num_sections; loop++ ) {
        error = ORLHashTableInsert( coff_file_hnd->sec_name_hash_table, (orl_hash_value) coff_file_hnd->coff_sec_hnd[loop]->name, coff_file_hnd->coff_sec_hnd[loop] );
        if( error != ORL_OKAY ) return( error );
    }
    return( ORL_OKAY );
}

orl_reloc_type CoffConvertRelocType( coff_file_handle coff_file_hnd, coff_reloc_type coff_type ) {
    if( coff_file_hnd->machine_type == ORL_MACHINE_TYPE_ALPHA ) {
        switch( coff_type ) {
            case IMAGE_REL_ALPHA_ABSOLUTE:
                return( ORL_RELOC_TYPE_ABSOLUTE );
            case IMAGE_REL_ALPHA_REFLONG:
            case IMAGE_REL_ALPHA_REFQUAD:
                return( ORL_RELOC_TYPE_WORD_32 );
            case IMAGE_REL_ALPHA_BRADDR:
                return( ORL_RELOC_TYPE_REL_21_SH );
            case IMAGE_REL_ALPHA_REFHI:
            case IMAGE_REL_ALPHA_INLINE_REFLONG:
                return( ORL_RELOC_TYPE_HALF_HI );
            case IMAGE_REL_ALPHA_REFLO:
                return( ORL_RELOC_TYPE_HALF_LO );
            case IMAGE_REL_ALPHA_PAIR:
                return( ORL_RELOC_TYPE_PAIR );
            case IMAGE_REL_ALPHA_SECTION:
                return( ORL_RELOC_TYPE_SEGMENT );
            case IMAGE_REL_ALPHA_SECREL:
                return( ORL_RELOC_TYPE_SEC_REL );
            case IMAGE_REL_ALPHA_REFLONGNB:
                return( ORL_RELOC_TYPE_WORD_32_NB );
            default:
                return( ORL_RELOC_TYPE_NONE );
        }
    } else if( coff_file_hnd->machine_type == ORL_MACHINE_TYPE_I386 ) {
        switch( coff_type ) {
            case IMAGE_REL_I386_ABSOLUTE:
                return( ORL_RELOC_TYPE_ABSOLUTE );
            case IMAGE_REL_I386_DIR16:
                return( ORL_RELOC_TYPE_WORD_16 );
            case IMAGE_REL_I386_REL16:
                return( ORL_RELOC_TYPE_REL_16 );
            case IMAGE_REL_I386_DIR32:
                return( ORL_RELOC_TYPE_WORD_32 );
            case IMAGE_REL_I386_DIR32NB:
                return( ORL_RELOC_TYPE_WORD_32_NB );
            case IMAGE_REL_I386_REL32:
                return( ORL_RELOC_TYPE_JUMP );
            case IMAGE_REL_I386_SECTION:
                return( ORL_RELOC_TYPE_SECTION );
            case IMAGE_REL_I386_SECREL:
                return( ORL_RELOC_TYPE_SEC_REL );
            default:
                return( ORL_RELOC_TYPE_NONE );
        }
    } else if( coff_file_hnd->machine_type == ORL_MACHINE_TYPE_AMD64 ) {
        switch( coff_type ) {
            case IMAGE_REL_AMD64_REL32:              // 32-Bit PC-relative offset
                return( ORL_RELOC_TYPE_REL_32 );
            case IMAGE_REL_AMD64_ADDR32:
                return( ORL_RELOC_TYPE_WORD_32 );
            case IMAGE_REL_AMD64_REL32_1:
                return( ORL_RELOC_TYPE_REL_32_ADJ1 );
            case IMAGE_REL_AMD64_REL32_2:
                return( ORL_RELOC_TYPE_REL_32_ADJ2 );
            case IMAGE_REL_AMD64_REL32_3:
                return( ORL_RELOC_TYPE_REL_32_ADJ3 );
            case IMAGE_REL_AMD64_REL32_4:

⌨️ 快捷键说明

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