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 + -
显示快捷键?