linkutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 617 行 · 第 1/2 页
C
617 行
/****************************************************************************
*
* 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: Utility routines for wlink.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include "linkstd.h"
#include "pcobj.h"
#include "newmem.h"
#include "alloc.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "linkutil.h"
#include "fileio.h"
#include "ring.h"
#include "overlays.h"
#include "strtab.h"
#include "loadfile.h"
#include "permdata.h"
#include "mapio.h"
#include "wressetr.h" // from wres project
static void WalkList( node *list, void (*fn)( void * ) );
static int ResWrite( int dummy, const void *buff, size_t size )
/*************************************************************/
/* redirect wres write to writeload */
{
dummy = dummy;
DbgAssert( dummy == Root->outfile->handle );
WriteLoad( (void *) buff, size );
return( size );
}
extern int WLinkItself;
static long ResSeek( int handle, off_t position, int where )
/**********************************************************/
/* Workaround wres bug */
{
if( ( where == SEEK_SET ) && ( handle == WLinkItself ) ) {
return( QLSeek( handle, position + FileShift, where, NULL ) - FileShift );
} else {
return( QLSeek( handle, position, where, NULL ) );
}
}
static int ResClose( int handle )
/*******************************/
{
return( close( handle ) );
}
static int ResRead( int handle, void * buffer, size_t len )
/*********************************************************/
{
return( QRead( handle, buffer, len, NULL ) );
}
static long ResPos( int handle )
/******************************/
{
return( QPos( handle ) );
}
WResSetRtns( ResOpen, ResClose, ResRead, ResWrite, ResSeek, ResPos, ChkLAlloc, LFree );
#if !defined( _DLLHOST )
extern void WriteStdOut( char *str )
/**********************************/
{
QWrite( STDOUT_HANDLE, str, strlen( str ), NULL );
}
extern void WriteNLStdOut( void )
/*******************************/
{
QWriteNL( STDOUT_HANDLE, NULL );
}
extern void WriteInfoStdOut( char *str, unsigned level, char *sym )
/*****************************************************************/
{
level = level;
sym = sym;
WriteStdOut( str );
WriteNLStdOut();
}
extern char * GetEnvString( char *envname )
/*****************************************/
{
return( getenv( envname ) );
}
extern bool GetAddtlCommand( unsigned cmd, char *buf )
/****************************************************/
{
cmd = cmd;
buf = buf;
return( FALSE );
}
extern bool IsStdOutConsole( void )
/*********************************/
{
return( QIsDevice( STDOUT_HANDLE ) );
}
#endif
extern void WriteNulls( f_handle file, unsigned_32 len, char * name )
/*******************************************************************/
/* copy nulls for uninitialized data */
{
static unsigned NullArray[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for( ; len > sizeof( NullArray ); len -= sizeof( NullArray ) ) {
QWrite( file, NullArray, sizeof( NullArray ), name );
}
if( len > 0 ) {
QWrite( file, NullArray, len, name );
}
}
extern void CheckErr( void )
/**************************/
{
if( LinkState & ( LINK_ERROR | STOP_WORKING ) ) {
WriteLibsUsed();
Suicide();
}
}
extern void CheckStop( void )
/***************************/
{
if( LinkState & STOP_WORKING ) {
Suicide();
}
}
extern void LnkFatal( char * msg )
/********************************/
{
LnkMsg( FTL+MSG_INTERNAL, "s", msg );
}
extern bool TestBit( byte * array, unsigned num )
/***********************************************/
/* return TRUE if the specified bit is on */
{
byte mask;
mask = 1 << ( num % 8 );
num /= 8;
return( *( array + num ) & mask );
}
extern void ClearBit( byte * array, unsigned num )
/************************************************/
/* make sure a bit is turned off */
{
byte mask;
mask = 1 << ( num % 8 );
num /= 8;
array += num;
*array &= ~mask;
}
extern char * ChkStrDup( char * str )
/***********************************/
{
size_t len;
char * copy;
len = strlen( str ) + 1;
_ChkAlloc( copy, len );
memcpy( copy, str, len );
return( copy );
}
extern void * ChkMemDup( void * mem, unsigned len )
/**************************************************/
{
char * copy;
_ChkAlloc( copy, len );
memcpy( copy, mem, len );
return( copy );
}
static void WalkModList( section *sect, void *rtn )
/*************************************************/
{
CurrSect = sect;
WalkList( (node *) sect->mods, rtn );
}
extern void WalkMods( void (*rtn)( mod_entry * ) )
/************************************************/
{
ParmWalkAllSects( WalkModList, rtn );
CurrSect = Root;
WalkList( (node *)LibModules, (void (*)(void *))rtn );
}
static void WalkClass( class_entry *class, void (*rtn)( seg_leader * ) )
/********************************************************************/
{
RingWalk( class->segs, (void (*)(void *))rtn );
}
extern void SectWalkClass( section *sect, void *rtn )
/***************************************************/
{
class_entry * class;
CurrSect = sect;
for( class = sect->classlist; class != NULL; class = class->next_class ) {
WalkClass( class, rtn );
}
}
extern void WalkLeaders( void (*rtn)( seg_leader * ) )
/****************************************************/
{
ParmWalkAllSects( SectWalkClass, rtn );
}
static void WalkList( node *list, void (*fn)( void * ) )
/******************************************************/
{
while( list != NULL ) {
fn( list );
list = list->next;
}
}
static bool CmpSegName( void *leader, void *name )
/************************************************/
{
return( stricmp( ((seg_leader *)leader)->segname, name ) == 0 );
}
extern seg_leader * FindSegment( char *name )
/*******************************************/
/* NOTE: this doesn't work for overlays! */
{
class_entry *class;
seg_leader * seg;
seg = NULL;
for( class = Root->classlist; class != NULL; class = class->next_class ) {
seg = RingLookup( class->segs, CmpSegName, name );
if( seg != NULL ) {
break;
}
}
return( seg );
}
extern void LinkList( void **in_head, void *newnode )
/***************************************************/
/* Link a new node into a linked list (new node goes at the end of the list) */
{
node ** owner;
owner = in_head;
((node *)newnode)->next = NULL;
while( *owner != NULL ) {
owner = &(*owner)->next;
}
*owner = newnode;
}
extern void FreeList( void *_curr )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?