browsio.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 483 行
C
483 行
/****************************************************************************
*
* 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: Browse database file I/O.
*
****************************************************************************/
#include "plusplus.h"
#include <stdio.h>
#include <setjmp.h>
#include <stdarg.h>
#include <malloc.h>
#include <errno.h>
#include "preproc.h"
#include "errdefns.h"
#include "memmgr.h"
#include "srcfile.h"
#include "dwio.h"
#include "iosupp.h"
#include "cgsegid.h"
#include "hfile.h"
#include "dw.h"
#include "exeelf.h"
#if defined(__UNIX__)
#include <unistd.h>
#else
#include <direct.h>
#endif
typedef struct cppdw_section {
DWFILE *file;
unsigned long offset;
unsigned long length;
} CPPDW_SECTION;
static CPPDW_SECTION dw_sections[DW_DEBUG_MAX];
// -- code to generate ELF output ------------------------------------------
//
// note: the pre-initialized fields in these structures assume the following
// layout in the file
// elf_header
// string_table
// .debug_abbrev
// .debug_info
// .WATCOM_references
// .debug_line
// .debug_macinfo
// section_header_index0
// section_header_string_table
// section_header_template( .debug_abbrev )
// section_header_template( .debug_info )
// section_header_template( .WATCOM_references )
// section_header_template( .debug_line )
// section_header_template( .debug_macinfo )
//
static Elf32_Ehdr elf_header = {
{ ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
ELFCLASS32, ELFDATA2LSB, EV_CURRENT },
ET_DYN,
EM_386,
EV_CURRENT,
0,
0,
0,//<offset of section table>=sizeof(Elf32_Ehdr)+sizeof(string_table)+sizes of 5 sections
0,
sizeof( Elf32_Ehdr ),
sizeof( Elf32_Phdr ),
0,
sizeof( Elf32_Shdr ),
7,
1
};
#define STR_NAME0 "\0"
#define STR_SHSTRTAB ".shstrtab\0"
#define STR_DBG_ABBREV ".debug_abbrev\0"
#define STR_DBG_INFO ".debug_info\0"
#define STR_DBG_REF ".WATCOM_references\0"
#define STR_DBG_LINE ".debug_line\0"
#define STR_DBG_MACINFO ".debug_macinfo\0"
#define OFF_NAME0 (0)
#define OFF_SHSTRTAB (OFF_NAME0 + sizeof( STR_NAME0 ) - 1)
#define OFF_DBG_ABBREV (OFF_SHSTRTAB + sizeof( STR_SHSTRTAB ) - 1)
#define OFF_DBG_INFO (OFF_DBG_ABBREV + sizeof( STR_DBG_ABBREV ) - 1)
#define OFF_DBG_REF (OFF_DBG_INFO + sizeof( STR_DBG_INFO ) - 1)
#define OFF_DBG_LINE (OFF_DBG_REF + sizeof( STR_DBG_REF ) - 1)
#define OFF_DBG_MACINFO (OFF_DBG_LINE + sizeof( STR_DBG_LINE ) - 1)
#define OFF_MAX (OFF_DBG_MACINFO + sizeof( STR_DBG_MACINFO ) - 1)
static char const string_table[OFF_MAX + 1] = {
STR_NAME0
STR_SHSTRTAB
STR_DBG_ABBREV
STR_DBG_INFO
STR_DBG_REF
STR_DBG_LINE
STR_DBG_MACINFO
};
static unsigned const string_table_offsets[] = {
OFF_DBG_ABBREV,
OFF_DBG_INFO,
OFF_DBG_REF,
OFF_DBG_LINE,
OFF_DBG_MACINFO
};
static Elf32_Shdr const section_header_index0 = {
0, SHT_NULL, 0, 0, 0, 0, SHN_UNDEF, 0, 0, 0
};
static Elf32_Shdr const section_header_string_table = {
OFF_SHSTRTAB,
SHT_STRTAB,
0,
0,
sizeof( Elf32_Ehdr ),
sizeof( string_table ),
SHN_UNDEF,
0,
0,
0
};
static Elf32_Shdr section_header_template = {
0,//<index of name in string section>
SHT_PROGBITS,
0,
0,
0,//<offset of section in file>
0,//<size of section>
SHN_UNDEF,
0,
0,
0
};
static void mywrite( FILE *fp, void *data, size_t len ) {
size_t wroteSize;
wroteSize = fwrite( data, 1, len, fp );
if (wroteSize < len) {
puts( strerror( errno ) );
CFatal( "error on write" );
}
}
static int createBrowseFile(FILE* browseFile, /* target file */
CPPDW_SECTION* abbrevFile, /* .debug_abbrev section */
CPPDW_SECTION* debugFile, /* .debug_info section */
CPPDW_SECTION* referenceFile, /* .WATCOM_reference section */
CPPDW_SECTION* lineFile, /* .debug_line section */
CPPDW_SECTION* macroFile /* .debug_macinfo section */
)
{
char *ptr;
size_t readSize;
int fileNum;
CPPDW_SECTION* inFile[5];
unsigned long sectionSize;
unsigned long sectionOffset[5];
// write elf header
elf_header.e_shoff = sizeof( Elf32_Ehdr )
+ sizeof( string_table )
+ abbrevFile->length
+ debugFile->length
+ referenceFile->length
+ lineFile->length
+ macroFile->length;
mywrite( browseFile, (void *)&elf_header, sizeof( elf_header ) );
// write string table
mywrite( browseFile, (void *)string_table, sizeof( string_table ) );
// write each of the 5 sections, tracking offset
inFile[0] = abbrevFile;
inFile[1] = debugFile;
inFile[2] = referenceFile;
inFile[3] = lineFile;
inFile[4] = macroFile;
sectionOffset[0] = sizeof( elf_header ) + sizeof( string_table );
sectionOffset[1] = sectionOffset[0] + inFile[0]->length;
sectionOffset[2] = sectionOffset[1] + inFile[1]->length;
sectionOffset[3] = sectionOffset[2] + inFile[2]->length;
sectionOffset[4] = sectionOffset[3] + inFile[3]->length;
for (fileNum=0;fileNum<5;fileNum++) {
DwioOpenInput( inFile[fileNum]->file );
readSize = 0;
sectionSize = inFile[fileNum]->length;
while( sectionSize ) {
ptr = DwioRead( inFile[fileNum]->file, &readSize );
readSize = min( readSize, sectionSize );
sectionSize -= readSize;
mywrite( browseFile, (void *)ptr, readSize );
}
DwioCloseInputFile( inFile[fileNum]->file );
}
// write section_header_index0
mywrite( browseFile, (void *)§ion_header_index0,
sizeof( section_header_index0 ) );
// write section_header_string_table
mywrite( browseFile, (void *)§ion_header_string_table,
sizeof( section_header_string_table ) );
// write rest of section headers
for (fileNum=0;fileNum<5;fileNum++) {
section_header_template.sh_name = string_table_offsets[fileNum];
section_header_template.sh_offset = sectionOffset[fileNum];
section_header_template.sh_size = inFile[fileNum]->length;
mywrite( browseFile, (void *)§ion_header_template,
sizeof( section_header_template ) );
}
return 0;
}
//---------------------------------------------------------------------------
static void dw_write( dw_sectnum section, const void *block, dw_size_t len )
/********************************************************************/
{
#ifdef __DD__
//int i;
printf( "\nDW_WRITE(%d:%d): offset: %d len: %d ",
section,
dw_sections[section].length,
dw_sections[section].offset,
len );
//for( i = 0 ; i < len; i++ ) {
// printf( "%02x ", (int)((char *)block)[i] );
//}
#endif
dw_sections[section].offset += len;
if( dw_sections[section].offset > dw_sections[section].length ) {
dw_sections[section].length = dw_sections[section].offset;
}
DwioWrite( dw_sections[section].file, (void *)block, len );
}
static long dw_tell( dw_sectnum section )
/*********************************/
{
#ifdef __DD__
printf( "DW_TELL (%d:%d): %d\n", section,
dw_sections[section].length,
dw_sections[section].offset );
#endif
return dw_sections[section].offset;
}
static void dw_reloc( dw_sectnum section, dw_relocs reloc_type, ... )
/********************************************************/
{
va_list args;
dw_targ_addr targ_data;
dw_targ_seg seg_data;
uint_32 u32_data;
uint sect;
SYMBOL sym;
va_start( args, reloc_type );
switch( reloc_type ) {
case DW_W_LABEL:
case DW_W_DEFAULT_FUNCTION:
case DW_W_ARANGE_ADDR:
case DW_W_LOW_PC:
u32_data = 0; // NOTE: assumes little-endian byte order
dw_write( section, &u32_data, TARGET_NEAR_POINTER );
break;
case DW_W_HIGH_PC:
u32_data = 1; // NOTE: assumes little-endian byte order
dw_write( section, &u32_data, TARGET_NEAR_POINTER );
break;
case DW_W_UNIT_SIZE:
u32_data = 1;
dw_write( section, &u32_data, sizeof( u32_data ) );
break;
case DW_W_STATIC:
sym = va_arg( args, SYMBOL );
targ_data = 0;
dw_write( section, &targ_data, sizeof( targ_data ) );
break;
case DW_W_SEGMENT:
sym = va_arg( args, SYMBOL );
seg_data = CgSegId( sym );
dw_write( section, &seg_data, sizeof( seg_data ) );
break;
case DW_W_SECTION_POS:
sect = va_arg( args, uint );
u32_data = dw_tell( sect );
dw_write( section, &u32_data, sizeof( u32_data ) );
break;
}
va_end( args );
}
static void dw_seek( dw_sectnum section, long offset, uint mode )
/*********************************************************/
{
switch( mode ) {
case DW_SEEK_SET:
break;
case DW_SEEK_CUR:
offset = dw_sections[section].offset + offset;
break;
case DW_SEEK_END:
offset = dw_sections[section].length - offset;
break;
}
#ifdef __DD__
printf( "DW_SEEK (%d:%d): offset: %d\n",
section,
dw_sections[section].length,
offset );
#endif
if( dw_sections[section].offset != offset ) {
DwioSeek( dw_sections[section].file, offset );
dw_sections[section].offset = offset;
if( dw_sections[section].offset > dw_sections[section].length ) {
dw_sections[section].length = dw_sections[section].offset;
}
}
}
static void *dw_alloc( size_t size )
/**********************************/
{
return CMemAlloc( size );
}
static void dw_free( void *ptr )
/******************************/
{
CMemFree( ptr );
}
extern dw_client DwarfInit( void )
/********************************/
{
dw_init_info info;
dw_cu_info cu;
char dir[_MAX_PATH2];
char fname[_MAX_PATH];
char * full_fname;
int i;
char * incbuf;
char * inccurr;
unsigned incsize;
dw_client client;
DwioInit();
for( i = 0 ; i < DW_DEBUG_MAX ; i++ ) {
dw_sections[i].file = DwioCreateFile();
dw_sections[i].offset = 0;
dw_sections[i].length = 0;
}
HFileListStart();
incsize = HFileListSize();
if( incsize != 0 ) {
incbuf = CMemAlloc( incsize );
inccurr = incbuf;
for(;;) {
HFileListNext( inccurr );
if( *inccurr == '\0' ) break;
inccurr = strend( inccurr ) + 1;
}
incsize = inccurr - incbuf;
}
info.language = DWLANG_CPP;
info.compiler_options = DW_CM_BROWSER;
info.producer_name = "WATCOM C++ V1";
memcpy( info.exception_handler, Environment, sizeof( jmp_buf ) );
info.funcs.reloc = &dw_reloc;
info.funcs.write = &dw_write;
info.funcs.seek = &dw_seek;
info.funcs.tell = &dw_tell;
info.funcs.alloc = &dw_alloc;
info.funcs.free = &dw_free;
client = DWInit( &info );
if( client == NULL ) {
CFatal( "dwarf: error in DWInit()" );
}
getcwd( dir, sizeof( dir ) ),
full_fname = IoSuppFullPath( WholeFName, fname, sizeof( fname ) );
cu.source_filename = full_fname;
cu.directory = dir;
cu.flags = 1;
cu.offset_size = TARGET_NEAR_POINTER;
cu.segment_size = 0;
cu.model = DW_MODEL_NONE;
cu.inc_list = incbuf;
cu.inc_list_len = incsize;
cu.dbg_pch = NULL;
DWBeginCompileUnit( client, &cu );
if( incsize != 0 ) {
CMemFree( incbuf );
}
return( client );
}
extern void DwarfFini( dw_client client )
/****************************************/
{
int i;
int status;
char *out_fname;
FILE *out_file;
if( !CompFlags.emit_browser_info ) return;
DWEndCompileUnit( client );
DWFini( client );
// close after writing
for( i = 0 ; i < DW_DEBUG_MAX ; i++ ) {
DwioCloseOutputFile( dw_sections[i].file );
}
out_fname = IoSuppOutFileName( OFT_MBR );
out_file = SrcFileFOpen( out_fname, SFO_WRITE_BINARY );
if( out_file == NULL ) {
puts( strerror( errno ) );
puts( out_fname );
CFatal( "dwarf: unable to open file for writing" );
}
// concatenate files
if( createBrowseFile( out_file,
&dw_sections[DW_DEBUG_ABBREV],
&dw_sections[DW_DEBUG_INFO],
&dw_sections[DW_DEBUG_REF],
&dw_sections[DW_DEBUG_LINE],
&dw_sections[DW_DEBUG_MACINFO] ) ) {
puts( strerror( errno ) );
CFatal( "dwarf: error in merging browse files" );
}
status = SrcFileFClose( out_file );
if( status ) {
puts( strerror( errno ) );
puts( out_fname );
CFatal( "dwarf: unable to close file" );
}
// delete
for( i = 0 ; i < DW_DEBUG_MAX ; i++ ) {
DwioFreeFile( dw_sections[i].file );
}
DwioFini();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?