loadnov.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 733 行 · 第 1/2 页
C
733 行
/****************************************************************************
*
* 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: routines for creating novell netware load files
*
****************************************************************************/
#include <string.h>
#include <time.h>
#include "linkstd.h"
#include "alloc.h"
#include "msg.h"
#include "exenov.h"
#include "dbginfo.h"
#include "reloc.h"
#include "wlnkmsg.h"
#include "virtmem.h"
#include "fileio.h"
#include "dbgall.h"
#include "impexp.h"
#include "loadfile.h"
#include "loadnov.h"
static unsigned_32 WriteNovData( unsigned_32, fixed_header * );
static unsigned_32 WriteNovImage( unsigned_32, bool );
#define DUMMY_THREAD_NAME " LONG"
static unsigned_32 DbgInfoCount;
static unsigned_32 DbgInfoLen;
static virt_mem NovDbgInfo;
static virt_mem CurrDbgLoc;
extern void ResetLoadNov( void )
/******************************/
{
DbgInfoCount = 0;
DbgInfoLen = 0;
}
static unsigned_32 WriteNovRelocs( fixed_header *header )
/*******************************************************/
// write the relocations.
{
DumpRelocList( Root->reloclist );
header->numberOfRelocationFixups = Root->relocs;
return( (unsigned_32)Root->relocs * sizeof( nov_reloc_item ) );
}
static unsigned_32 WriteNovImports( fixed_header *header )
/********************************************************/
{
nov_import * import;
unsigned_32 count;
char * name;
unsigned_8 namelen;
unsigned_32 wrote;
unsigned_32 refs;
virt_mem * vmem_array;
symbol * sym;
wrote = count = 0;
for( sym = HeadSym; sym != NULL; sym = sym->link ) {
if( !( IS_SYM_IMPORTED( sym ) ) )
continue;
/* so SymFini doesn't try to free it */
if( sym->p.import == DUMMY_IMPORT_PTR )
sym->p.import = NULL;
import = sym->p.import;
if( import != NULL ) {
count++;
name = sym->name;
namelen = strlen( name );
/*
// netware prefix support
*/
if( sym->prefix ) {
namelen += ( strlen( sym->prefix ) + 1);
WriteLoad( &namelen, sizeof( unsigned_8 ) );
WriteLoad( sym->prefix, strlen( sym->prefix ) );
WriteLoad( "@", 1 );
WriteLoad( name, strlen( sym->name ) );
} else {
WriteLoad( &namelen, sizeof( unsigned_8 ) );
WriteLoad( name, namelen );
}
wrote += namelen + sizeof( unsigned_8 ) + sizeof( unsigned_32 );
if( import->contents <= MAX_IMP_INTERNAL ) {
refs = import->contents;
WriteLoad( &refs, sizeof( unsigned_32 ) );
refs *= sizeof( unsigned_32 );
WriteLoad( &import->num_relocs, refs );
} else { // imports are in virtual memory.
refs = import->num_relocs;
WriteLoad( &refs, sizeof( unsigned_32 ) );
vmem_array = import->addr;
while( refs > IMP_NUM_VIRT ) {
WriteInfo( *vmem_array, IMP_VIRT_ALLOC_SIZE );
vmem_array++;
refs -= IMP_NUM_VIRT;
}
WriteInfo( *vmem_array, refs * sizeof( unsigned_32 ) );
refs = import->num_relocs * sizeof( unsigned_32 );
}
wrote += refs;
}
}
header->numberOfExternalReferences = count;
return( wrote );
}
static unsigned_32 WriteNovExports( fixed_header *header )
/********************************************************/
{
name_list * export;
symbol * sym;
unsigned_32 count;
unsigned_32 wrote;
unsigned_32 off;
unsigned_8 len;
count = wrote = 0;
export = FmtData.u.nov.exp.export;
while( export != NULL ) {
len = export->len;
sym = SymOp( ST_FIND, export->name, len );
if( ( sym == NULL ) || !( sym->info & SYM_DEFINED ) ) {
LnkMsg( WRN+MSG_EXP_SYM_NOT_FOUND, "s", export->name );
} else if( !IS_SYM_IMPORTED(sym) ) {
/*
// netware prefix support
*/
if( sym->prefix ) {
char full_name[255+1];
strcpy(full_name, sym->prefix);
strcat(full_name, "@");
strcat(full_name, sym->name);
AddImpLibEntry( sym->name, full_name, NOT_IMP_BY_ORDINAL );
len = strlen( full_name );
WriteLoad( &len, sizeof( unsigned_8 ) );
WriteLoad( full_name, len );
} else {
AddImpLibEntry( sym->name, sym->name, NOT_IMP_BY_ORDINAL );
WriteLoad( &len, sizeof( unsigned_8 ) );
WriteLoad( export->name, len );
}
count++;
off = sym->addr.off;
if( sym->addr.seg == CODE_SEGMENT ) {
off |= NOV_EXP_ISCODE;
}
WriteLoad( &off, sizeof( unsigned_32 ) );
wrote += sizeof( unsigned_32 ) + sizeof( unsigned_8 ) + len;
}
export = export->next;
}
header->numberOfPublics = count;
return( wrote );
}
static unsigned_32 WriteNovModules( fixed_header *header )
/********************************************************/
{
name_list * module;
unsigned_32 count;
unsigned_32 wrote;
count = wrote = 0;
module = FmtData.u.nov.exp.module;
while( module != NULL ) {
count++;
WriteLoad( &module->len, sizeof( unsigned_8 ) );
WriteLoad( module->name, module->len );
wrote += sizeof( unsigned_8 ) + module->len;
module = module->next;
}
header->numberOfModuleDependencies = count;
return( wrote );
}
extern void NovDBIAddGlobal( void * _sym )
/****************************************/
{
symbol *sym = _sym;
if( !IS_SYM_A_REF(sym)
&& !IS_SYM_ALIAS(sym)
&& ( sym->p.seg != NULL )
&& !( sym->info & SYM_DEAD )
&& !sym->p.seg->isabs
&& !( sym->info & SYM_STATIC )
&& !( FmtData.u.nov.flags & DO_NOV_EXPORTS ) ) {
DbgInfoLen += strlen( sym->name ) + sizeof( nov_dbg_info );
}
}
extern void NovDBIAddrStart( void )
/*********************************/
{
if( DbgInfoLen != 0 ) {
NovDbgInfo = AllocStg( DbgInfoLen );
CurrDbgLoc = NovDbgInfo;
}
}
extern void NovDBIGenGlobal( symbol *sym )
/****************************************/
{
nov_dbg_info info;
if( ( DbgInfoLen != 0 )
&& ( !( FmtData.u.nov.flags & DO_NOV_REF_ONLY )
|| ( sym->info & SYM_REFERENCED ) ) ) {
DbgInfoCount++;
if( sym->addr.seg == DATA_SEGMENT ) {
info.type = DBG_DATA;
} else {
info.type = DBG_CODE;
}
info.offset = sym->addr.off;
info.namelen = strlen( sym->name );
PutInfo( CurrDbgLoc, &info, sizeof( nov_dbg_info ) );
CurrDbgLoc += sizeof( nov_dbg_info );
PutInfo( CurrDbgLoc, sym->name, info.namelen );
CurrDbgLoc += info.namelen;
}
}
static unsigned_32 WriteNovDBI( fixed_header *header )
/****************************************************/
{
name_list * export;
symbol * sym;
unsigned_32 count;
unsigned_32 wrote;
unsigned_8 len;
nov_dbg_info info;
if( DbgInfoLen > 0 ) {
WriteInfo( NovDbgInfo, CurrDbgLoc - NovDbgInfo );
header->numberOfDebugRecords = DbgInfoCount;
return( CurrDbgLoc - NovDbgInfo );
} else if( FmtData.u.nov.flags & DO_NOV_EXPORTS ) {
count = wrote = 0;
export = FmtData.u.nov.exp.export;
while( export != NULL ) {
len = export->len;
sym = SymOp( ST_FIND, export->name, len );
if( ( sym != NULL ) && !IS_SYM_IMPORTED( sym ) ) {
count++;
if( sym->addr.seg == DATA_SEGMENT ) {
info.type = DBG_DATA;
} else {
info.type = DBG_CODE;
}
info.offset = sym->addr.off;
info.namelen = len;
WriteLoad( &info, sizeof( nov_dbg_info ) );
WriteLoad( export->name, len );
wrote += sizeof( nov_dbg_info ) + len;
}
export = export->next;
}
header->numberOfDebugRecords = count;
return( wrote );
}
header->numberOfDebugRecords = 0;
return( 0 );
}
static unsigned_32 WriteMessages( extended_nlm_header * header )
/**************************************************************/
/* write out the messages file */
{
f_handle handle;
char * name;
unsigned_32 buf[2];
name = FmtData.u.nov.messages;
header->messageFileLength = 0;
if( name != NULL ) {
handle = QOpenR( name );
QRead( handle, TokBuff, MSG_FILE_SIGNATURE_LENGTH, name );
if( memcmp( TokBuff, MSG_FILE_SIGNATURE, MSG_FILE_SIGNATURE_LENGTH ) != 0 ) {
LnkMsg( WRN+MSG_INV_MESSAGE_FILE, "s", name );
QClose( handle, name );
} else {
QSeek( handle, LANGUAGE_ID_OFFSET, name );
QRead( handle, buf, 2*sizeof( unsigned_32 ), name );
header->languageID = buf[0];
header->messageCount = buf[1];
QSeek( handle, 0, name );
header->messageFileLength = CopyToLoad( handle, name );
}
}
return( header->messageFileLength );
}
static unsigned_32 WriteSharedNLM( extended_nlm_header * header,
unsigned_32 file_size )
/*********************************************************************/
{
f_handle handle;
char * name;
fixed_header * sharehdr;
name = FmtData.u.nov.sharednlm;
if( name != NULL ) {
handle = QOpenR( name );
QRead( handle, TokBuff, sizeof( fixed_header ), name );
if( memcmp( TokBuff, NLM_SIGNATURE, sizeof( NLM_SIGNATURE ) - 1 ) != 0 ) {
LnkMsg( WRN+MSG_INV_SHARED_NLM_FILE, "s", name );
QClose( handle, name );
} else {
sharehdr = (fixed_header *) TokBuff;
header->sharedCodeOffset = sharehdr->codeImageOffset + file_size;
header->sharedCodeLength = sharehdr->codeImageSize;
header->sharedDataOffset = sharehdr->dataImageOffset + file_size;
header->sharedDataLength = sharehdr->dataImageSize;
header->sharedRelocationFixupOffset
= sharehdr->relocationFixupOffset + file_size;
header->sharedRelocationFixupCount
= sharehdr->numberOfRelocationFixups;
header->sharedExternalReferenceOffset
= sharehdr->externalReferencesOffset + file_size;
header->sharedExternalReferenceCount
= sharehdr->numberOfExternalReferences;
header->sharedPublicsOffset = sharehdr->publicsOffset + file_size;
header->sharedPublicsCount = sharehdr->numberOfPublics;
header->sharedDebugRecordOffset
= sharehdr->debugInfoOffset + file_size;
header->sharedDebugRecordCount = sharehdr->numberOfDebugRecords;
header->sharedInitializationOffset = sharehdr->codeStartOffset;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?