dbgdwarf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 880 行 · 第 1/3 页
C
880 行
/****************************************************************************
*
* 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 producing DWARF debugging information.
*
****************************************************************************/
#include <string.h>
#include <setjmp.h>
#include "walloca.h"
#include "linkstd.h"
#include "alloc.h"
#include "objcalc.h"
#include "ring.h"
#include "exeelf.h"
#include "strtab.h"
#include "tistrail.h"
#include "dwarf.h"
#include "dw.h"
#include "dwutils.h"
#include "loadfile.h"
#include "virtmem.h"
#include "objnode.h"
#include "dbgcomm.h"
#include "dbgdwarf.h"
#include "fileio.h"
#include "loadelf.h"
#include "specials.h"
static class_entry * DBIClass; // Assume there is only one!
typedef struct {
virt_mem addr;
unsigned_32 size;
} dwarfsect;
typedef struct dwarfmodinfo {
dwarfsect pubsym;
dwarfsect dasi;
dwarfsect arange;
} dwarfmodinfo;
// this used to hold information about linker generated debugging information.
typedef struct {
virt_mem addr; // virt. mem. block containing genned info.
unsigned_32 size; // size of linker generated info.
unsigned_32 start; // start of linker generated info - compiler stuff 1st
char * name;
} sectioninfo;
static sectioninfo SectionTable[] = {
{ 0, 0, 0, ".debug_info" },
{ 0, 0, 0, ".debug_abbrev" },
{ 0, 0, 0, ".debug_line" },
{ 0, 0, 0, ".debug_aranges" }
};
enum {
SECT_DEBUG_INFO, // assumed to be in the same order as segment flags!
SECT_DEBUG_ABBREV,
SECT_DEBUG_LINE,
SECT_DEBUG_ARANGE,
SECT_NUM_SECTIONS
};
#pragma pack( 1 )
// die information
typedef struct {
unsigned_8 abbrev_code; // the abbrev code used.
// unsigned_32 stmt_list; // (optional) offset to the line number info
// char name[1]; // name of the module
} compunit_die;
typedef struct {
unsigned_8 abbrev_code;
offset off;
unsigned_8 isexternal;
// char name[1];
} symbol_die;
typedef struct {
unsigned_8 len;
unsigned_8 loc_op;
unsigned_16 seg;
} symbol_seg;
// the abbrev codes used in the linker's autogenned stuff.
#define NULL_ABBREV_CODE 0
#define COMPUNIT_ABBREV_CODE 1
#define CU_NOLINE_ABBREV_CODE 2
#define LABEL_ABBREV_CODE 3
#define VARIABLE_ABBREV_CODE 4
#define LAST_ABBREV_CODE 4
#if LAST_ABBREV_CODE != LAST_LINKER_ABBREV
#error "make sure dwarf.h is updated and dwarf writing library recompiled!"
#endif
static char SegmentedStandardAbbrevs[] = {
COMPUNIT_ABBREV_CODE,
DW_TAG_compile_unit,
DW_CHILDREN_yes,
DW_AT_stmt_list, DW_FORM_ref_addr,
DW_AT_name, DW_FORM_string,
0, 0,
CU_NOLINE_ABBREV_CODE,
DW_TAG_compile_unit,
DW_CHILDREN_yes,
DW_AT_name, DW_FORM_string,
0, 0,
LABEL_ABBREV_CODE,
DW_TAG_label,
DW_CHILDREN_no,
DW_AT_low_pc, DW_FORM_addr,
DW_AT_external, DW_FORM_flag,
DW_AT_segment, DW_FORM_block1,
DW_AT_name, DW_FORM_string,
0, 0,
VARIABLE_ABBREV_CODE,
DW_TAG_variable,
DW_CHILDREN_no,
DW_AT_low_pc, DW_FORM_addr,
DW_AT_external, DW_FORM_flag,
DW_AT_segment, DW_FORM_block1,
DW_AT_name, DW_FORM_string,
0, 0
};
static char FlatStandardAbbrevs[] = {
COMPUNIT_ABBREV_CODE,
DW_TAG_compile_unit,
DW_CHILDREN_yes,
DW_AT_stmt_list, DW_FORM_ref_addr,
DW_AT_name, DW_FORM_string,
0, 0,
CU_NOLINE_ABBREV_CODE,
DW_TAG_compile_unit,
DW_CHILDREN_yes,
DW_AT_name, DW_FORM_string,
0, 0,
LABEL_ABBREV_CODE,
DW_TAG_label,
DW_CHILDREN_no,
DW_AT_low_pc, DW_FORM_addr,
DW_AT_external, DW_FORM_flag,
DW_AT_name, DW_FORM_string,
0, 0,
VARIABLE_ABBREV_CODE,
DW_TAG_variable,
DW_CHILDREN_no,
DW_AT_low_pc, DW_FORM_addr,
DW_AT_external, DW_FORM_flag,
DW_AT_name, DW_FORM_string,
0, 0
};
#pragma pack()
static void DwarfAddLines( segdata *, void *, unsigned, bool );
extern void DwarfInit( void )
/***************************/
{
int index;
DBIClass = NULL;
for( index = 0; index < SECT_NUM_SECTIONS; index++ ) {
SectionTable[index].addr = 0;
SectionTable[index].size = 0;
SectionTable[index].start = 0;
}
}
extern void DwarfInitModule( mod_entry *mod )
/*******************************************/
{
_PermAlloc( mod->d.d, sizeof( dwarfmodinfo ) );
memset( mod->d.d, 0, sizeof( dwarfmodinfo ) );
}
extern void DwarfP1ModuleScanned( void )
/**************************************/
{
}
extern void DwarfP1ModuleFinished( mod_entry *mod )
/*************************************************/
{
if( MOD_NOT_DEBUGGABLE( mod ) )
return;
CurrMod = mod;
if( mod->modinfo & MOD_DBI_SEEN )
return;
DBILineWalk( mod->lines, DwarfAddLines );
Ring2Walk( mod->publist, DBIModGlobal );
if( FmtData.type & MK_SEGMENTED ) {
SectionTable[SECT_DEBUG_ABBREV].size = sizeof( SegmentedStandardAbbrevs );
} else {
SectionTable[SECT_DEBUG_ABBREV].size = sizeof( FlatStandardAbbrevs );
}
if( mod->d.d->dasi.size > 0 ) {
mod->d.d->dasi.addr = SectionTable[SECT_DEBUG_LINE].size;
mod->d.d->dasi.size += strlen( mod->name ) + sizeof( stmt_prologue ) + 6;
SectionTable[SECT_DEBUG_LINE].size += mod->d.d->dasi.size;
mod->d.d->pubsym.size += sizeof( unsigned_32 ); // DW_AT_STMT_LIST
}
mod->d.d->pubsym.addr = SectionTable[SECT_DEBUG_INFO].size;
mod->d.d->pubsym.size += strlen( mod->name ) + sizeof( compunit_die ) + 1
+ COMPILE_UNIT_HDR_SIZE + 1;
SectionTable[SECT_DEBUG_INFO].size += mod->d.d->pubsym.size;
}
extern void DwarfStoreAddrInfo( mod_entry *mod )
/**********************************************/
{
if( !( mod->modinfo & MOD_DBI_SEEN ) ) {
if( mod->d.d->arange.size > 0 ) {
mod->d.d->arange.addr = SectionTable[SECT_DEBUG_ARANGE].size;
mod->d.d->arange.size += sizeof( arange_prologue );
if( FmtData.type & MK_SEGMENTED ) {
mod->d.d->arange.size += sizeof( segmented_arange_tuple );
} else {
mod->d.d->arange.size += sizeof( flat_arange_tuple );
}
SectionTable[SECT_DEBUG_ARANGE].size += mod->d.d->arange.size;
}
}
}
extern void DwarfAddModule( mod_entry *mod, section *sect )
/*********************************************************/
// this generates the headers needed in the individual sections
{
arange_prologue arange_hdr;
stmt_prologue stmt_hdr;
compuhdr_prologue compuhdr;
compunit_die die;
size_t namelen;
char * buff;
unsigned_32 stmt_list;
sect = sect;
if( !( mod->modinfo & MOD_DBI_SEEN ) ) {
namelen = strlen( mod->name );
if( mod->d.d->arange.size > 0 ) {
mod->d.d->arange.addr += SectionTable[SECT_DEBUG_ARANGE].addr;
arange_hdr.length = mod->d.d->arange.size - sizeof( unsigned_32 );
arange_hdr.version = 2;
arange_hdr.debug_offset = mod->d.d->pubsym.addr
+ SectionTable[SECT_DEBUG_INFO].start;
arange_hdr.offset_size = sizeof( offset );
if( FmtData.type & MK_SEGMENTED ) {
arange_hdr.segment_size = sizeof( segment );
} else {
arange_hdr.segment_size = 0;
}
// memset( arange_hdr.padding, 0, sizeof( arange_hdr.padding ) );
PutInfo( mod->d.d->arange.addr, (void *)&arange_hdr,
sizeof( arange_prologue ) );
mod->d.d->arange.addr += sizeof( arange_prologue );
}
mod->d.d->pubsym.addr += SectionTable[SECT_DEBUG_INFO].addr;
compuhdr.length = mod->d.d->pubsym.size - sizeof( unsigned_32 );
compuhdr.version = 2;
compuhdr.abbrev_offset = SectionTable[SECT_DEBUG_ABBREV].start;
compuhdr.addr_size = sizeof( offset );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?