permdata.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:  Routines for making some linker data permanent.
*
****************************************************************************/


#include <string.h>
#include <stdio.h>
#include "linkstd.h"
#include "strtab.h"
#include "dbgcomm.h"
#include "dbgall.h"
#include "carve.h"
#include "alloc.h"
#include "command.h"
#include "reloc.h"
#include "fileio.h"
#include "virtmem.h"
#include "impexp.h"
#include "loadfile.h"
#include "msg.h"
#include "objio.h"
#include "ring.h"
#include "wlnkmsg.h"
#include "objcalc.h"
#include "permdata.h"

stringtable             PermStrings;
stringtable             PrefixStrings;  /* these are NetWare prefix strings of which there could possibly be several */
carve_t                 CarveLeader;
carve_t                 CarveModEntry;
carve_t                 CarveSymbol;
carve_t                 CarveSegData;
carve_t                 CarveClass;
carve_t                 CarveGroup;
carve_t                 CarveDLLInfo;
carve_t                 CarveExportInfo;
char *                  IncFileName;
incgroupdef *           IncGroupDefs;
group_entry **          IncGroups;
libnamelist *           SavedUserLibs;
libnamelist *           SavedDefLibs;

static stringtable      StoredRelocs;
static char *           ReadRelocs;
static unsigned         SizeRelocs;
static char *           OldExe;
static char *           OldSymFile;
static void *           AltDefData;
static char *           IncStrTab;

#define SEG_CARVE_SIZE          (2*1024)
#define MOD_CARVE_SIZE          (5*1024)
#define SDATA_CARVE_SIZE        (16*1024)
#define SYM_CARVE_SIZE          (32*1024)

static void BufWritePermFile( perm_write_info *info, void *data, unsigned len );
static void DoWritePermFile( perm_write_info *info, char *data, unsigned len,
                             bool isvmem );

extern void ResetPermData( void )
/******************************/
{
    IncFileName = NULL;
    IncStrTab = NULL;
    ReadRelocs = NULL;
    OldExe = NULL;
    AltDefData = NULL;
    OldSymFile = NULL;
    IncGroupDefs = NULL;
    IncGroups = NULL;
    SavedUserLibs = NULL;
    SavedDefLibs = NULL;
    CarveClass = CarveCreate( sizeof(class_entry), 20 * sizeof(class_entry) );
    CarveGroup = CarveCreate( sizeof(group_entry), 20 * sizeof(group_entry) );
    CarveDLLInfo = CarveCreate( sizeof(dll_sym_info), 100*sizeof(dll_sym_info));
    CarveExportInfo = CarveCreate(sizeof(entry_export),20*sizeof(entry_export));
    CarveLeader = CarveCreate( sizeof(seg_leader), SEG_CARVE_SIZE );
    CarveModEntry = CarveCreate( sizeof(mod_entry), MOD_CARVE_SIZE );
    CarveSegData = CarveCreate( sizeof(segdata), SDATA_CARVE_SIZE );
    CarveSymbol = CarveCreate( sizeof(symbol), SYM_CARVE_SIZE );
    InitStringTable( &PermStrings, TRUE );
    InitStringTable( &PrefixStrings, TRUE );
    InitStringTable( &StoredRelocs, FALSE );
}


static void MarkDLLInfo( void *dll )
/**********************************/
{
    ((dll_sym_info *)dll)->isfree = TRUE;
}

static void MarkExportInfo( void *exp )
/*************************************/
{
    ((entry_export *)exp)->isfree = TRUE;
}

static void MarkModEntry( void *mod )
/***********************************/
{
    ((mod_entry *)mod)->modinfo |= MOD_IS_FREE;
}

static void MarkSegData( void *sdata )
/************************************/
{
    ((segdata *)sdata)->isfree = TRUE;
}

static void MarkSymbol( void *sym )
/*********************************/
{
    ((symbol *)sym)->info |= SYM_IS_FREE;
}

static void * GetString( perm_write_info *info, char *str )
/*********************************************************/
{
    unsigned idx;

    idx = GetStringTableSize( &info->strtab );
    StringStringTable( &info->strtab, str );
    return (void *)idx;
}

static bool WriteLeaderName( void *_leader, void *info )
/*****************************************************/
{
    seg_leader *leader = _leader;

    BufWritePermFile( info, &leader->class->name, sizeof(unsigned_32) );
    BufWritePermFile( info, &leader->segname, sizeof(unsigned_32) );
    return FALSE;
}

static unsigned WriteGroups( perm_write_info *info )
/**************************************************/
{
    group_entry *group;
    unsigned    num;
    unsigned_32 count;

    num = 0;
    for( group = Groups; group != NULL; group = group->next_group ) {
        if( !group->isautogrp && group->leaders != NULL ) {
            num++;
            count = Ring2Count( group->leaders );
            BufWritePermFile( info, &count, sizeof(unsigned_32) );
            group->sym->name = GetString( info, group->sym->name );
            BufWritePermFile( info, &group->sym->name, sizeof(unsigned_32) );
            Ring2Lookup( group->leaders, WriteLeaderName, info );
        }
    }
    return num;
}

static bool CheckFree( bool isfree, perm_write_info *info )
/*********************************************************/
{
    unsigned_32 dummy;

    if( isfree ) {
        dummy = CARVE_INVALID_INDEX;
        BufWritePermFile( info, &dummy, sizeof(unsigned_32) );
    }
    return isfree;
}

static void WriteDLLInfo( void *_dll, void *info )
/************************************************/
{
    dll_sym_info *dll = _dll;

    if( !CheckFree( dll->isfree, info ) ) {
        dll->m.modname = dll->m.modnum->name;
        if( !dll->isordinal ) {
            dll->u.entname = dll->u.entry->name;
        }
        BufWritePermFile( info, dll, offsetof(dll_sym_info, iatsym) );
    }
}

static void WriteExportInfo( void *_exp, void *info )
/***************************************************/
{
    entry_export *exp = _exp;

    if( !CheckFree( exp->isfree, info ) ) {
        exp->next = CarveGetIndex( CarveExportInfo, exp->next );
        if( exp->name != NULL ) {
            exp->name = GetString( info, exp->name );
        }
        BufWritePermFile( info, exp, offsetof(entry_export, sym) );
    }
}

static void FixSymAddr( void *_sym )
/**********************************/
{
    symbol *sym = _sym;

    if( !IS_SYM_IMPORTED(sym) && !(sym->info & SYM_DEAD) && sym->addr.off > 0
                                                     && sym->p.seg != NULL ) {
        sym->addr.off -= sym->p.seg->u.leader->seg_addr.off;
        sym->addr.off -= sym->p.seg->a.delta;
    }
}

static void PrepModEntry( void *_mod, void *info )
/************************************************/
{
    mod_entry *mod = _mod;

    if( mod->modinfo & MOD_IS_FREE ) {
        *((unsigned_32 *)mod) = CARVE_INVALID_INDEX;
        return;
    }
    Ring2Walk( mod->publist, FixSymAddr );
    mod->n.next_mod = CarveGetIndex( CarveModEntry, mod->n.next_mod );
    mod->name = GetString( info, mod->name );
    mod->publist = CarveGetIndex( CarveSymbol, mod->publist );
    mod->segs = CarveGetIndex( CarveSegData, mod->segs );
    mod->modinfo &= ~MOD_CLEAR_ON_INC;
    if( mod->f.source != NULL ) {
        mod->f.fname = mod->f.source->file->name;
    }
}

static void PrepSegData( void *_sdata, void *info )
/*************************************************/
{
    segdata *sdata = _sdata;
    info = info;
    if( sdata->isfree ) {
        *((unsigned_32 *)sdata) = CARVE_INVALID_INDEX;
        return;
    }
    sdata->next = CarveGetIndex( CarveSegData, sdata->next );  // not used
    sdata->mod_next = CarveGetIndex( CarveSegData, sdata->mod_next );
    sdata->o.clname = sdata->u.leader->class->name;
    sdata->u.name = sdata->u.leader->segname;
}

static void PrepSymbol( void *_sym, void *info )
/**********************************************/
{
    symbol *    sym = _sym;
    char *      save;
    symbol *    mainsym;

    if( sym->info & SYM_IS_FREE ) {
        *((unsigned_32 *)sym) = CARVE_INVALID_INDEX;
        return;
    }
    sym->hash = CarveGetIndex( CarveSymbol, sym->hash );
    sym->link = CarveGetIndex( CarveSymbol, sym->link );
    sym->publink = CarveGetIndex( CarveSymbol, sym->publink );
    if( sym->info & SYM_IS_ALTDEF ) {
        mainsym = sym->e.mainsym;
        if( !(mainsym->info & SYM_NAME_XLATED) ) {
            mainsym->name = GetString( info, mainsym->name );
            mainsym->info |= SYM_NAME_XLATED;
        }
        sym->name = mainsym->name;
    } else if( !(sym->info & SYM_NAME_XLATED) ) {
        sym->name = GetString( info, sym->name );
        sym->info |= SYM_NAME_XLATED;
    }
    sym->mod = CarveGetIndex( CarveModEntry, sym->mod );
    if( IS_SYM_ALIAS( sym ) ) {
        save = sym->p.alias;
        sym->p.alias = GetString( info, sym->p.alias );
        if( sym->info & SYM_FREE_ALIAS ) {
            _LnkFree( save );
        }
    } else if( IS_SYM_IMPORTED(sym) ) {
        if( FmtData.type & (MK_OS2 | MK_PE) ) {
            sym->p.import = CarveGetIndex( CarveDLLInfo, sym->p.import );
        }
    } else if( !(sym->info & SYM_IS_ALTDEF) || IS_SYM_COMDAT(sym) ) {
        sym->p.seg = CarveGetIndex( CarveSegData, sym->p.seg );
        sym->u.altdefs = CarveGetIndex( CarveSymbol, sym->u.altdefs );
    }
    if( sym->info & SYM_EXPORTED ) {
        if( FmtData.type & (MK_OS2 | MK_PE | MK_WIN_VXD) ) {
            sym->e.export = CarveGetIndex( CarveExportInfo, sym->e.export );
        }
    } else if( sym->e.def != NULL ) {
        sym->e.def = CarveGetIndex( CarveSymbol, sym->e.def );
    }
}

static void PrepNameTable( name_list *list, perm_write_info *info )
/*****************************************************************/
{
    char *      savename;

    while( list != NULL ) {
        savename = list->name;
        list->name = (char *) GetStringTableSize( &info->strtab );
        AddStringTable( &info->strtab, savename, list->len + 1 );
        list = list->next;
    }
}

static void PrepFileList( perm_write_info *info )
/***********************************************/
{
    infilelist *list;
    char *      path_ptr;
    char *      name;
    char        new_name[ PATH_MAX ];

    for( list = CachedFiles; list != NULL; list = list->next ) {
        if( list->prefix != NULL ) {
            path_ptr = list->prefix;
            QMakeFileName( &path_ptr, list->name, new_name );
            name = new_name;
        } else {
            name = list->name;
        }
        list->name = GetString( info, name );
    }
}

static bool PrepLeaders( void *_leader, void *info )
/**************************************************/
{
    seg_leader *leader = _leader;

    leader->segname = GetString( info, leader->segname );
    return FALSE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?