owelf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 481 行 · 第 1/2 页
C
481 行
/****************************************************************************
*
* 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: Emit ELF object.
*
****************************************************************************/
#include "owlpriv.h"
#include "owreloc.h"
#define MAX_SECTION_NAME 128
#define ELF_UNDEF_INDEX 0
#define ELF_STRING_INDEX 1 /* index of string table section */
#define ELF_SYMBOL_INDEX 2 /* index of symbol table section */
#define FIRST_USER_SECTION 3
#define _OWLIndexToELFIndex( x ) ( (x) + FIRST_USER_SECTION )
static int useRela; // Use .rela or .rel
static unsigned numSections( owl_file_handle file ) {
//***************************************************
return( _OWLIndexToELFIndex( file->next_index ) );
}
static unsigned numSymbols( owl_file_handle file ) {
//**************************************************
return( file->symbol_table->num_global_symbols +
file->symbol_table->num_local_symbols );
}
// must correspond to owl_cpu in owl.h
static Elf32_Half machineTypes[] = { EM_PPC, EM_ALPHA, EM_MIPS, EM_386 };
static void writeFileHeader( owl_file_handle file ) {
//***************************************************
Elf32_Ehdr header;
memset( &header.e_ident[ 0 ], 0, sizeof( header.e_ident ) );
header.e_ident[ EI_MAG0 ] = ELFMAG0;
header.e_ident[ EI_MAG1 ] = ELFMAG1;
header.e_ident[ EI_MAG2 ] = ELFMAG2;
header.e_ident[ EI_MAG3 ] = ELFMAG3;
header.e_ident[ EI_CLASS ] = ELFCLASS32;
#if defined( __BIG_ENDIAN__ )
header.e_ident[ EI_DATA ] = ELFDATA2MSB;
#else
header.e_ident[ EI_DATA ] = ELFDATA2LSB;
#endif
header.e_ident[ EI_VERSION ] = EV_CURRENT;
header.e_type = ET_REL;
header.e_machine = machineTypes[ file->info->cpu ];
header.e_version = EV_CURRENT;
header.e_entry = 0; // fixme - should allow client to set this
header.e_phoff = 0;
header.e_shoff = sizeof( header ); // follows immediately after the file header
header.e_flags = 0; // FIXME - get right stuff from IBM buttheads
header.e_ehsize = sizeof( header );
header.e_phentsize = sizeof( Elf32_Phdr );
header.e_phnum = 0;
header.e_shentsize = sizeof( Elf32_Shdr );
header.e_shnum = numSections( file );
header.e_shstrndx = ELF_STRING_INDEX;
_ClientWrite( file, (const char *)&header, sizeof( header ) );
}
static void prepareStringTable( owl_file_handle file, elf_special_section *str_sect ) {
//*************************************************************************************
// Before we can use indices for owl_string_handles, we
// have to write the string table into a temporary buffer
str_sect->length = OWLStringTableSize( file->string_table );
str_sect->buffer = _ClientAlloc( file, str_sect->length );
OWLStringEmit( file->string_table, str_sect->buffer );
}
// must correspond to owl_sym_linkage in owl.h
static Elf32_Half elfBinding[] = { STB_GLOBAL, STB_LOCAL, STB_LOCAL, STB_GLOBAL, STB_WEAK };
// must correspond to owl_sym_type in owl.h
static Elf32_Half elfType[] = { STT_FUNC, STT_OBJECT, STT_SECTION, STT_FILE };
static void emitElfSymbol( owl_symbol_info *symbol, Elf32_Sym *elf_sym ) {
//************************************************************************
elf_sym->st_name = OWLStringOffset( symbol->name );
elf_sym->st_value = symbol->offset;
elf_sym->st_size = 0;
elf_sym->st_info = ELF32_ST_INFO( elfBinding[ symbol->linkage ], elfType[ symbol->type ] );
elf_sym->st_other = 0;
elf_sym->st_shndx = SHN_UNDEF;
if( symbol->section != NULL ) {
elf_sym->st_shndx = _OWLIndexToELFIndex( symbol->section->index );
}
}
static void emitBogusSymbol( Elf32_Sym *elf_sym ) {
//*************************************************
elf_sym->st_name = 0;
elf_sym->st_value = 0;
elf_sym->st_size = 0;
elf_sym->st_info = 0;
elf_sym->st_other = 0;
elf_sym->st_shndx = SHN_UNDEF;
}
static void prepareSymbolTable( owl_file_handle file, elf_special_section *sym_sect ) {
//*************************************************************************************
// Same as for prepareStringTable, but with symbols instead of strings. Since symbol
// table entries are format-specific, we don't have a handy OWLSymbol call to do all
// our work for us, so we just run the table converting everything
owl_symbol_info *sym;
unsigned next_local_index;
unsigned next_global_index;
Elf32_Sym *elf_syms;
sym_sect->length = ( numSymbols( file ) + 1 ) * sizeof( Elf32_Sym );
sym_sect->buffer = _ClientAlloc( file, sym_sect->length );
elf_syms = (Elf32_Sym *)sym_sect->buffer;
emitBogusSymbol( elf_syms );
next_local_index = 1;
next_global_index = file->symbol_table->num_global_symbols + file->symbol_table->num_local_symbols;
for( sym = file->symbol_table->head; sym != NULL; sym = sym->next ) {
if( sym->flags & OWL_SYM_DEAD ) continue;
if( !(_OwlLinkageGlobal(sym->linkage)) ) {
sym->index = next_local_index++;
} else {
sym->index = next_global_index--;
}
emitElfSymbol( sym, &elf_syms[ sym->index ] );
}
assert( ( next_global_index + 1 ) == next_local_index );
assert( next_local_index == ( file->symbol_table->num_local_symbols + 1 ) );
}
static void initSectionHeader( Elf32_Shdr *header, Elf32_Word type, Elf32_Word flags ) {
//**************************************************************************************
header->sh_name = 0;
header->sh_type = type;
header->sh_flags = flags;
header->sh_addr = 0;
header->sh_offset = 0;
header->sh_size = 0;
header->sh_link = SHN_UNDEF;
header->sh_info = 0;
header->sh_addralign = 0;
header->sh_entsize = 0;
}
static void formatBogusUndefHeader( owl_file_handle file, Elf32_Shdr *header ) {
//******************************************************************************
file = file;
initSectionHeader( header, SHT_NULL, 0 );
}
static void formatStringTableHeader( owl_file_handle file, Elf32_Shdr *header ) {
//*******************************************************************************
initSectionHeader( header, SHT_STRTAB, 0 );
header->sh_name = OWLStringOffset( file->x.elf.string_table.name );
header->sh_offset = file->x.elf.next_section;
header->sh_size = file->x.elf.string_table.length;
file->x.elf.next_section += file->x.elf.string_table.length;
}
static void formatSymbolTableHeader( owl_file_handle file, Elf32_Shdr *header ) {
//*******************************************************************************
elf_special_section *sym_tab;
sym_tab = &file->x.elf.symbol_table;
initSectionHeader( header, SHT_SYMTAB, 0 );
header->sh_name = OWLStringOffset( sym_tab->name );
header->sh_link = ELF_STRING_INDEX;
header->sh_info = file->symbol_table->num_local_symbols + 1;
header->sh_entsize = sizeof( Elf32_Sym );
header->sh_offset = file->x.elf.next_section;
header->sh_size = sym_tab->length;
file->x.elf.next_section += sym_tab->length;
}
static Elf32_Word sectionTypes( owl_section_type type ) {
//*******************************************************
if( type & OWL_SEC_ATTR_CODE ) return( SHT_PROGBITS );
if( type & OWL_SEC_ATTR_DATA ) return( SHT_PROGBITS );
if( type & OWL_SEC_ATTR_BSS ) return( SHT_NOBITS );
if( type & OWL_SEC_ATTR_INFO ) return( SHT_NOTE );
return( SHT_NULL );
}
static Elf32_Word sectionFlags( owl_section_type type ) {
//*******************************************************
uint_32 flags = 0;
if( type & OWL_SEC_ATTR_CODE ) flags |= SHF_ALLOC;
if( type & OWL_SEC_ATTR_DATA ) flags |= SHF_ALLOC;
if( type & OWL_SEC_ATTR_BSS ) flags |= SHF_ALLOC;
if( type & OWL_SEC_ATTR_PERM_WRITE ) flags |= SHF_WRITE;
if( type & OWL_SEC_ATTR_PERM_EXEC ) flags |= SHF_EXECINSTR;
return( flags );
}
static uint_32 sectionAlignment( owl_section_info *section )
//**********************************************************
{
uint_32 alignment = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?