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

📄 elfload.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:  Top level ELF loading code, parses ELF headers.
*
****************************************************************************/


#include "elfload.h"

// fixme: finish making ELF SPECIFIC (see next fixme)

static void fix_ehdr_byte_order( elf_file_handle elf_file_hnd, Elf32_Ehdr *e_hdr )
{
    // note that one of the branches will always get compiled out,
    // depending on host endianness
    if( elf_file_hnd->flags & ORL_FILE_FLAG_BIG_ENDIAN ) {
        CONV_BE_16( e_hdr->e_type );
        CONV_BE_16( e_hdr->e_machine );
        CONV_BE_32( e_hdr->e_version );
        CONV_BE_32( e_hdr->e_entry );
        CONV_BE_32( e_hdr->e_phoff );
        CONV_BE_32( e_hdr->e_shoff );
        CONV_BE_32( e_hdr->e_flags );
        CONV_BE_16( e_hdr->e_ehsize );
        CONV_BE_16( e_hdr->e_phentsize );
        CONV_BE_16( e_hdr->e_phnum );
        CONV_BE_16( e_hdr->e_shentsize );
        CONV_BE_16( e_hdr->e_shnum );
        CONV_BE_16( e_hdr->e_shstrndx );
    } else {
        CONV_LE_16( e_hdr->e_type );
        CONV_LE_16( e_hdr->e_machine );
        CONV_LE_32( e_hdr->e_version );
        CONV_LE_32( e_hdr->e_entry );
        CONV_LE_32( e_hdr->e_phoff );
        CONV_LE_32( e_hdr->e_shoff );
        CONV_LE_32( e_hdr->e_flags );
        CONV_LE_16( e_hdr->e_ehsize );
        CONV_LE_16( e_hdr->e_phentsize );
        CONV_LE_16( e_hdr->e_phnum );
        CONV_LE_16( e_hdr->e_shentsize );
        CONV_LE_16( e_hdr->e_shnum );
        CONV_LE_16( e_hdr->e_shstrndx );
    }
}


static void fix_shdr_byte_order( elf_file_handle elf_file_hnd, Elf32_Shdr *e_shdr )
{
    // note that one of the branches will always get compiled out,
    // depending on host endianness
    if( elf_file_hnd->flags & ORL_FILE_FLAG_BIG_ENDIAN ) {
        CONV_BE_32( e_shdr->sh_name );
        CONV_BE_32( e_shdr->sh_type );
        CONV_BE_32( e_shdr->sh_flags );
        CONV_BE_32( e_shdr->sh_addr );
        CONV_BE_32( e_shdr->sh_offset );
        CONV_BE_32( e_shdr->sh_size );
        CONV_BE_32( e_shdr->sh_link );
        CONV_BE_32( e_shdr->sh_info );
        CONV_BE_32( e_shdr->sh_addralign );
        CONV_BE_32( e_shdr->sh_entsize );
    } else {
        CONV_LE_32( e_shdr->sh_name );
        CONV_LE_32( e_shdr->sh_type );
        CONV_LE_32( e_shdr->sh_flags );
        CONV_LE_32( e_shdr->sh_addr );
        CONV_LE_32( e_shdr->sh_offset );
        CONV_LE_32( e_shdr->sh_size );
        CONV_LE_32( e_shdr->sh_link );
        CONV_LE_32( e_shdr->sh_info );
        CONV_LE_32( e_shdr->sh_addralign );
        CONV_LE_32( e_shdr->sh_entsize );
    }
}


// This function needs to be run before anything else, because it determines
// how the rest of the data is to be interpreted
static void determine_file_class( elf_file_handle elf_file_hnd, Elf32_Ehdr *e_hdr )
{
    elf_file_hnd->flags = 0;
    switch( e_hdr->e_ident[EI_DATA] ) {
    case ELFLITTLEENDIAN:
        elf_file_hnd->flags |= ORL_FILE_FLAG_LITTLE_ENDIAN;
        break;
    case ELFBIGENDIAN:
        elf_file_hnd->flags |= ORL_FILE_FLAG_BIG_ENDIAN;
        break;
    }
    switch( e_hdr->e_ident[EI_CLASS] ) {
    case ELFCLASS32:
        elf_file_hnd->flags |= ORL_FILE_FLAG_32BIT_MACHINE;
        break;
    case ELFCLASS64:
        elf_file_hnd->flags |= ORL_FILE_FLAG_64BIT_MACHINE;
        break;
    }
}


static void determine_file_specs( elf_file_handle elf_file_hnd, Elf32_Ehdr *e_hdr )
{
    switch( e_hdr->e_machine ) {
    case EM_M32:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_WE_2100;
        break;
    case EM_SPARC:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_SPARC;
        break;
    case EM_386:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_I386;
        break;
    case EM_68K:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_M68000;
        break;
    case EM_88K:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_M88000;
        break;
    case EM_860:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_I860;
        break;
    case EM_PPC:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_PPC601;
        break;
    case EM_MIPS:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_R3000;
        break;
    default:
        elf_file_hnd->machine_type = ORL_MACHINE_TYPE_NONE;
    }
    switch( e_hdr->e_type ) {
    case ET_REL:
        elf_file_hnd->type = ORL_FILE_TYPE_OBJECT;
        break;
    case ET_EXEC:
        elf_file_hnd->type = ORL_FILE_TYPE_EXECUTABLE;
        break;
    case ET_DYN:
        elf_file_hnd->type = ORL_FILE_TYPE_SHARED_OBJECT;
        break;
    case ET_CORE:
        elf_file_hnd->type = ORL_FILE_TYPE_CORE;
        break;
    default:
        elf_file_hnd->type = ORL_FILE_TYPE_NONE;
        break;
    }
// fixme:  add computer-specific (PPC) flags, if any!
}


static void determine_section_specs( elf_sec_handle elf_sec_hnd, Elf32_Shdr * s_hdr )
{
    elf_sec_hnd->flags = ORL_SEC_FLAG_READ_PERMISSION;
    switch( s_hdr->sh_type ) {
    case SHT_PROGBITS:
        elf_sec_hnd->type = ORL_SEC_TYPE_PROG_BITS;
        elf_sec_hnd->flags |= ORL_SEC_FLAG_INITIALIZED_DATA;
        break;
    case SHT_SYMTAB:
        elf_sec_hnd->type = ORL_SEC_TYPE_SYM_TABLE;
        break;
    case SHT_STRTAB:
        elf_sec_hnd->type = ORL_SEC_TYPE_STR_TABLE;
        break;
    case SHT_RELA:
        elf_sec_hnd->type = ORL_SEC_TYPE_RELOCS_EXPADD;
        break;
    case SHT_HASH:
        elf_sec_hnd->type = ORL_SEC_TYPE_HASH;
        break;
    case SHT_DYNAMIC:
        elf_sec_hnd->type = ORL_SEC_TYPE_DYNAMIC;
        break;
    case SHT_NOTE:
        elf_sec_hnd->type = ORL_SEC_TYPE_NOTE;
        break;
    case SHT_NOBITS:
        elf_sec_hnd->type = ORL_SEC_TYPE_NO_BITS;
        elf_sec_hnd->flags |= ORL_SEC_FLAG_UNINITIALIZED_DATA;
        break;
    case SHT_REL:
        elf_sec_hnd->type = ORL_SEC_TYPE_RELOCS;
        break;
    case SHT_DYNSYM:
        elf_sec_hnd->type = ORL_SEC_TYPE_DYN_SYM_TABLE;
        break;
    case SHT_OS:
    case SHT_OS_O:
        elf_sec_hnd->type = ORL_SEC_TYPE_PROG_BITS;
        break;
    case SHT_IMPORTS:
    case SHT_IMPORTS_O:
        elf_sec_hnd->type = ORL_SEC_TYPE_IMPORT;
        break;
    case SHT_EXPORTS:
    case SHT_EXPORTS_O:
        elf_sec_hnd->type = ORL_SEC_TYPE_EXPORT;
        break;
    case SHT_RES:
    case SHT_RES_O:
        elf_sec_hnd->type = ORL_SEC_TYPE_PROG_BITS;
        break;
    default:
        elf_sec_hnd->type = ORL_SEC_TYPE_NONE;
        break;
    }
    if( s_hdr->sh_flags & SHF_WRITE ) {
        elf_sec_hnd->flags |= ORL_SEC_FLAG_WRITE_PERMISSION;
    }
    if( !(s_hdr->sh_flags & SHF_ALLOC) ) {
        elf_sec_hnd->flags |= ORL_SEC_FLAG_REMOVE;
    }
    if( s_hdr->sh_flags & SHF_EXECINSTR ) {
        // set execute permission also?
        elf_sec_hnd->flags |= ORL_SEC_FLAG_EXEC;
    }
}


static void free_elf_sec_handles( elf_file_handle elf_file_hnd, int num_alloced )
{
    int         loop;

    if( elf_file_hnd->elf_sec_hnd != NULL ) {
        for( loop = 0; loop < num_alloced; loop++ ) {
            _ClientFree( elf_file_hnd, elf_file_hnd->elf_sec_hnd[loop] );
        }
        _ClientFree( elf_file_hnd, elf_file_hnd->elf_sec_hnd );
    } else {

⌨️ 快捷键说明

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