symtable.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,080 行 · 第 1/3 页
C
1,080 行
/****************************************************************************
*
* 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: Librarian symbol table processing.
*
****************************************************************************/
#include <wlib.h>
static sym_table FileTable;
sym_file *CurrFile;
static sym_entry **HashTable;
static sym_entry **SortedSymbols;
#define HASH_SIZE 256
static int Hash( char *string, unsigned *plen );
void InitFileTab( void )
/**********************/
{
FileTable.first = NULL;
FileTable.add_to = &FileTable.first;
SortedSymbols = NULL;
HashTable = MemAllocGlobal( HASH_SIZE * sizeof( HashTable[0] ) );
memset( HashTable, 0, HASH_SIZE * sizeof( HashTable[0] ) );
}
void FiniSymFile( sym_file *file )
/********************************/
{
sym_entry *sym, *next_sym;
elf_import_sym *temp;
for( sym = file->first; sym != NULL; sym = next_sym ) {
next_sym = sym->next;
MemFreeGlobal( sym );
}
MemFreeGlobal( file->full_name );
MemFreeGlobal( file->arch.name );
MemFreeGlobal( file->arch.ffname );
if( file->import != NULL ) {
switch( file->import->type ) {
case ELF:
case ELFRENAMED:
for( temp=file->import->symlist; temp!=NULL;
temp=file->import->symlist ) {
file->import->symlist = temp->next;
MemFreeGlobal( temp->name );
MemFreeGlobal( temp );
}
MemFreeGlobal( file->import->DLLName );
break;
default:
MemFreeGlobal( file->import->DLLName );
MemFreeGlobal( file->import->symName );
MemFreeGlobal( file->import->exportedName );
break;
}
MemFreeGlobal( file->import );
}
MemFreeGlobal( file );
}
void CleanFileTab( void )
/***********************/
{
sym_file *last = NULL;
sym_file *curr;
sym_file *next;
for (curr = FileTable.first; curr; curr = next) {
next = curr->next;
/*
* If curr->first is NULL then either this file contains no
* symbols or we are ignoring all of them. Remove the file.
*/
if (!curr->first) {
if (last) {
last->next = curr->next;
} else {
FileTable.first = curr->next;
}
if (&(curr->next) == FileTable.add_to) {
if (last) {
FileTable.add_to = &(last->next);
} else {
FileTable.add_to = &(FileTable.first);
}
}
FiniSymFile(curr);
} else {
last = curr;
}
} /* for */
} /* CleanFileTab() */
void ResetFileTab( void )
/***********************/
{
sym_file *file, *next_file;
memset( HashTable, 0, HASH_SIZE * sizeof( HashTable[0] ) );
for( file = FileTable.first; file != NULL; file = next_file ) {
next_file = file->next;
FiniSymFile( file );
}
FileTable.first = NULL;
FileTable.add_to = &FileTable.first;
MemFreeGlobal( SortedSymbols );
SortedSymbols = NULL;
}
void FiniFileTab( void )
/***********************/
{
MemFreeGlobal( HashTable );
}
void RemoveFromHashTable( sym_entry *sym )
/****************************************/
{
sym_entry *hash;
sym_entry *prev;
int hval;
unsigned len;
hval = Hash(sym->name, &len);
hash = HashTable[hval];
if (hash == sym) {
HashTable[hval] = sym->hash;
} else if (hash) {
prev = hash;
for (hash = hash->hash; hash; hash = hash->hash) {
if (hash == sym) {
prev->hash = hash->hash;
break;
} else {
prev = hash;
}
}
}
} /* RemoveFromHashTable() */
static void NewSymFile( arch_header *arch )
/*****************************************/
{
sym_file *file;
file = MemAllocGlobal( sizeof(sym_file) );
file->first = NULL;
file->next = NULL;
file->arch = *arch;
file->import = NULL;
file->inlib_offset = 0;
file->full_name = DupStrGlobal( file->arch.name );
file->arch.name = DupStrGlobal( TrimPath( file->arch.name ) ); // make own copy
file->name_length = strlen( file->arch.name );
if( file->arch.ffname ) {
file->arch.ffname = DupStrGlobal( file->arch.ffname );
file->ffname_length = strlen( file->arch.ffname );
} else {
file->ffname_length = 0;
}
*(FileTable.add_to) = file;
FileTable.add_to = &file->next;
CurrFile = file;
}
static int CompSyms( const void *ap, const void *bp )
/***************************************************/
{
const sym_entry *a = *(const sym_entry**)ap;
const sym_entry *b = *(const sym_entry**)bp;
return( strcmp( a->name, b->name ) );
}
static void WriteFileHeader( arch_header *arch )
/**********************************************/
{
ar_header ar;
CreateARHeader( &ar, arch );
WriteNew( &ar, AR_HEADER_SIZE );
}
static void WritePad( file_offset size )
/**************************************/
{
if( NeedsRounding( size ) ) {
WriteNew( AR_FILE_PADDING_STRING, 1 );
}
}
static long NumFiles;
static long NumSymbols;
static file_offset TotalNameLength;
static file_offset TotalFFNameLength;
static file_offset TotalSymbolLength;
static void SortSymbols( void )
/*****************************/
{
sym_file * file;
sym_entry * sym;
sym_entry **sym_curr;
int i;
int name_length = 0;
int name_extra = 0;
NumFiles = 0;
NumSymbols = 0;
TotalNameLength = 0;
TotalFFNameLength = 0;
TotalSymbolLength = 0;
switch( Options.libtype ) {
case WL_TYPE_AR:
name_extra = 1;
break;
case WL_TYPE_MLIB:
name_extra = 2;
break;
}
for( file = FileTable.first; file != NULL; file = file->next ) {
++NumFiles;
file->name_offset = TotalNameLength;
switch( Options.libtype ) {
case WL_TYPE_AR:
// Always using "full" filename for AR
if( file->arch.ffname ) {
name_length = file->ffname_length;
} else {
file->ffname_length = 0;
name_length = file->name_length;
}
break;
case WL_TYPE_MLIB:
// If no full filename, assume name is full, and trim
// it to get non-full filename.
if( file->arch.ffname == NULL ) {
file->arch.ffname = file->arch.name;
file->ffname_length = strlen( file->arch.ffname );
file->arch.name = MemAllocGlobal( _MAX_FNAME + _MAX_EXT + 1 );
_splitpath( file->arch.ffname, NULL, NULL, file->arch.name, NULL );
_splitpath( file->arch.ffname, NULL, NULL, NULL, file->arch.name + strlen( file->arch.name ) );
file->name_length = strlen( file->arch.name );
}
name_length = file->name_length;
break;
}
TotalNameLength += name_length + name_extra;
TotalFFNameLength += file->ffname_length + 1;
for( sym = file->first; sym != NULL; sym = sym->next ) {
++NumSymbols;
TotalSymbolLength += sym->len + 1;
}
}
if( NumSymbols == 0 ) {
SortedSymbols = NULL;
Warning( ERR_NO_SYMBOLS );
} else {
SortedSymbols = MemAllocGlobal( NumSymbols * sizeof( SortedSymbols[0] ) );
}
sym_curr = SortedSymbols;
for( file = FileTable.first; file != NULL; file = file->next ) {
for( sym = file->first; sym != NULL; sym = sym->next ) {
*sym_curr = sym;
++sym_curr;
}
}
qsort( SortedSymbols, NumSymbols, sizeof(sym_entry *), CompSyms );
// re-hook symbols onto files in sorted order
for( file = FileTable.first; file != NULL; file = file->next ) {
file->first = NULL;
}
for( i = NumSymbols - 1; i >= 0; --i ) {
sym = SortedSymbols[i];
sym->next = sym->file->first;
sym->file->first = sym;
}
}
static void WriteOmfFileTable( void )
/***********************************/
{
sym_file *file;
unsigned num_blocks;
unsigned dict_offset;
if( Options.page_size == 0 ){
Options.page_size = DEFAULT_PAGE_SIZE;
}
InitOmfUtil();
PadOmf( TRUE );
for( file = FileTable.first; file != NULL; file = file->next ) {
WriteOmfFile(file);
}
WriteOmfLibTrailer();
dict_offset = LibTell( NewLibrary );
num_blocks = WriteOmfDict( FileTable.first );
WriteOmfLibHeader( dict_offset, num_blocks );
FiniOmfUtil();
}
static void WriteArMlibFileTable( void )
/**************************************/
{
arch_header arch;
sym_file *file;
sym_entry *sym;
file_offset dict1_size = 0;
file_offset dict2_size = 0;
file_offset header_size = 0;
int i;
time_t currenttime = time( NULL );
file_offset obj_offset;
int index;
libfile io;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?