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