labproc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 331 行
C
331 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "global.h"
#include "dis.h"
#include "demangle.h"
#include "labproc.h"
#include "memfuncs.h"
#include "hashtabl.h"
#include "formasm.h"
extern wd_options Options;
extern hash_table HandleToLabelListTable;
extern hash_table SymbolToLabelTable;
extern publics_struct Publics;
extern char * SourceFileInObject;
extern dis_format_flags DFormat;
static label_entry resolveTwoLabelsAtLocation( label_list sec_label_list, label_entry entry, label_entry previous_entry, label_entry old_entry )
{
label_entry first_entry = old_entry;
for( ; old_entry != NULL && old_entry->offset == entry->offset; old_entry = old_entry->next ) {
if( entry->type == LTYP_UNNAMED ) {
if( old_entry->type == LTYP_UNNAMED ) {
MemFree( entry );
entry = old_entry;
return( entry );
} else if( old_entry->type == LTYP_NAMED ) {
MemFree( entry );
entry = old_entry;
return( entry );
} else if( old_entry->type == LTYP_ABSOLUTE ) {
} else if( old_entry->type == LTYP_FUNC_INFO ) {
} else if( old_entry->type == LTYP_SECTION ) {
if( !IsMasmOutput() ) {
MemFree( entry );
entry = old_entry;
return( entry );
}
} else {
MemFree( entry );
entry = old_entry;
return( entry );
}
} else if( entry->type == LTYP_ABSOLUTE ) {
if( old_entry->type == LTYP_ABSOLUTE ) {
// merge entry into old_entry
MemFree( entry );
entry = old_entry;
return( entry );
}
} else if( entry->type == LTYP_EXTERNAL_NAMED ) {
break;
} else {
}
}
// two labels for this location!
entry->next = first_entry;
if( previous_entry ) {
previous_entry->next = entry;
} else {
sec_label_list->first = entry;
}
return( entry );
}
static label_entry insertLabelInMiddle( label_list sec_label_list, label_entry entry )
{
label_entry walker;
label_entry previous_entry;
label_entry old_entry;
if( entry->offset == sec_label_list->first->offset ) {
old_entry = sec_label_list->first;
previous_entry = NULL;
} else {
walker = sec_label_list->first;
while( walker->next->offset < entry->offset ) {
walker = walker->next;
}
old_entry = walker->next;
previous_entry = walker;
}
if( old_entry->offset == entry->offset ) {
entry = resolveTwoLabelsAtLocation( sec_label_list, entry, previous_entry, old_entry );
} else {
entry->next = previous_entry->next;
previous_entry->next = entry;
}
return( entry );
}
static label_entry addLabel( label_list sec_label_list, label_entry entry, orl_symbol_handle sym_hnd )
{
if( sec_label_list->first == NULL ) {
sec_label_list->first = entry;
sec_label_list->last = entry;
entry->next = NULL;
} else if( entry->offset > sec_label_list->last->offset ) {
sec_label_list->last->next = entry;
sec_label_list->last = entry;
entry->next = NULL;
} else if( entry->offset < sec_label_list->first->offset ) {
entry->next = sec_label_list->first;
sec_label_list->first = entry;
} else {
// fixme: this shouldn't happen too often
// if it does, change to a skip list
entry = insertLabelInMiddle( sec_label_list, entry );
}
// add entry to list
if( sym_hnd != NULL ) {
HashTableInsert( SymbolToLabelTable, (hash_value) sym_hnd, (hash_data) entry );
}
return( entry );
}
bool NeedsQuoting( const char *name )
{
// If the name contains funny characters and we are producing
// assemblable output, put back-quotes around it.
if( !(DFormat & DFF_ASM) ) return( FALSE );
if( isdigit( *name ) ) return( TRUE );
while( *name ) {
if( isalnum( *name ) || *name == '_' || *name == '?' || *name == '$' ) {
/* OK character */
} else if( *name == '.' && !IsMasmOutput() ) {
/* OK character */
} else {
/* character needs quoting */
return( TRUE );
}
name++;
}
return( FALSE );
}
orl_return CreateNamedLabel( orl_symbol_handle sym_hnd )
{
hash_data * data_ptr;
label_list sec_label_list;
label_entry entry;
orl_symbol_type type;
orl_symbol_type primary_type;
orl_sec_handle sec;
char * SourceName;
char * LabName;
type = ORLSymbolGetType( sym_hnd );
primary_type = type & 0xFF;
switch( primary_type ) {
// No harm in including these since elf generates relocs to these.
// case ORL_SYM_TYPE_NONE:
// case ORL_SYM_TYPE_FUNC_INFO:
// return( ORL_OKAY );
case ORL_SYM_TYPE_FILE:
SourceName = ORLSymbolGetName( sym_hnd );
if( (SourceName != NULL) && (SourceFileInObject == NULL) ) {
SourceFileInObject = SourceName;
}
return( ORL_OKAY );
}
entry = MemAlloc( sizeof( label_entry_struct ) );
if( !entry ) return( ORL_OUT_OF_MEMORY );
entry->offset = (orl_sec_offset) ORLSymbolGetValue( sym_hnd );
// all symbols from the object file will have names
entry->shnd = ORLSymbolGetSecHandle( sym_hnd );
if( primary_type == ORL_SYM_TYPE_SECTION ) {
entry->type = LTYP_SECTION;
} else if( primary_type == ORL_SYM_TYPE_GROUP ) {
entry->type = LTYP_GROUP;
} else if( entry->shnd == 0 ) {
entry->type = LTYP_EXTERNAL_NAMED;
} else if( primary_type == ORL_SYM_TYPE_FUNC_INFO ){
entry->type = LTYP_FUNC_INFO;
} else {
entry->type = LTYP_NAMED;
}
entry->binding = ORLSymbolGetBinding( sym_hnd );
LabName = ORLSymbolGetName( sym_hnd );
if( LabName == NULL ) {
sec = ORLSymbolGetSecHandle( sym_hnd );
if( sec ) {
LabName = ORLSecGetName( sec );
} else {
MemFree( entry );
return( ORL_OKAY );
}
}
// Demangle the name, if necessary
if( !((Options & NODEMANGLE_NAMES) || (DFormat & DFF_ASM)) ) {
entry->label.name = MemAlloc( MAX_LINE_LEN + 3 );
__demangle_l( LabName, 0, &(entry->label.name[2]), MAX_LINE_LEN );
} else {
entry->label.name = MemAlloc( strlen( LabName )+8 );
strcpy( &(entry->label.name[2]), LabName );
}
entry->label.name[0]=0;
entry->label.name[1]=0;
LabName = &(entry->label.name[2]);
if( NeedsQuoting( LabName ) ) {
// entry->label.name[-1] will be 1 if we have added a quote,
// 0 otherwise. This is helpful when freeing the memory.
entry->label.name[0] = 1;
entry->label.name[1] = '`';
entry->label.name += 1;
LabName += strlen( LabName );
LabName[0] = '`';
LabName[1] = '\0';
} else {
entry->label.name += 2;
}
data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) entry->shnd );
if( data_ptr ) {
sec_label_list = (label_list) *data_ptr;
entry = addLabel( sec_label_list, entry, sym_hnd );
if( Options & PRINT_PUBLICS && entry->shnd != 0 &&
primary_type != ORL_SYM_TYPE_SECTION &&
entry->binding != ORL_SYM_BINDING_LOCAL ) {
Publics.number++;
}
} else {
// error!!!! the label list should have been created
MemFree( entry );
return( ORL_ERROR );
}
return( ORL_OKAY );
}
orl_return DealWithSymbolSection( orl_sec_handle shnd )
{
orl_return error;
error = ORLSymbolSecScan( shnd, CreateNamedLabel );
return( error );
}
void CreateUnnamedLabel( orl_sec_handle shnd, orl_sec_offset loc, unnamed_label_return return_struct )
{
label_list sec_label_list;
hash_data * data_ptr;
label_entry entry;
entry = MemAlloc( sizeof( label_entry_struct ) );
if( !entry ) {
return_struct->error = OUT_OF_MEMORY;
return;
}
entry->offset = loc;
entry->type = LTYP_UNNAMED;
entry->label.number = 0;
entry->shnd = shnd;
data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) shnd );
if( data_ptr ) {
sec_label_list = (label_list) *data_ptr;
entry = addLabel( sec_label_list, entry, 0 );
return_struct->entry = entry;
return_struct->error = OKAY;
} else {
// error!!!! the label list should have been created
return_struct->error = ERROR;
}
return;
}
void CreateAbsoluteLabel( orl_sec_handle shnd, orl_sec_offset loc, unnamed_label_return return_struct )
{
label_list sec_label_list;
hash_data * data_ptr;
label_entry entry;
entry = MemAlloc( sizeof( label_entry_struct ) );
if( !entry ) {
return_struct->error = OUT_OF_MEMORY;
return;
}
entry->offset = loc;
entry->type = LTYP_ABSOLUTE;
entry->label.number = 0;
entry->shnd = shnd;
data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) shnd );
if( data_ptr ) {
sec_label_list = (label_list) *data_ptr;
entry = addLabel( sec_label_list, entry, 0 );
return_struct->entry = entry;
return_struct->error = OKAY;
} else {
// error!!!! the label list should have been created
return_struct->error = ERROR;
}
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?