dbgdwarf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 880 行 · 第 1/3 页
C
880 行
PutInfo( mod->d.d->pubsym.addr, (void *) &compuhdr,
sizeof( compuhdr_prologue ) );
mod->d.d->pubsym.addr += sizeof( compuhdr_prologue );
if( mod->d.d->dasi.size > 0 ) {
die.abbrev_code = COMPUNIT_ABBREV_CODE;
} else {
die.abbrev_code = CU_NOLINE_ABBREV_CODE;
}
PutInfo( mod->d.d->pubsym.addr, &die, sizeof( compunit_die ) );
mod->d.d->pubsym.addr += sizeof( compunit_die );
if( mod->d.d->dasi.size > 0 ) {
stmt_list = mod->d.d->dasi.addr
+ SectionTable[SECT_DEBUG_LINE].start;
PutInfo( mod->d.d->pubsym.addr, &stmt_list, sizeof( unsigned_32 ) );
mod->d.d->pubsym.addr += sizeof( unsigned_32 );
}
PutInfo( mod->d.d->pubsym.addr, mod->name, namelen + 1 );
mod->d.d->pubsym.addr += namelen + 1;
if( mod->d.d->dasi.size > 0 ) {
mod->d.d->dasi.addr += SectionTable[SECT_DEBUG_LINE].addr;
stmt_hdr.total_length = mod->d.d->dasi.size - sizeof( unsigned_32 );
stmt_hdr.version = 2;
stmt_hdr.prologue_length = sizeof( stmt_prologue )
- offsetof( stmt_prologue, minimum_instruction_length )
+ namelen + 6;
stmt_hdr.minimum_instruction_length = DW_MIN_INSTR_LENGTH;
stmt_hdr.default_is_stmt = 1;
stmt_hdr.line_base = DWLINE_BASE;
stmt_hdr.line_range = DWLINE_RANGE;
stmt_hdr.opcode_base = DWLINE_OPCODE_BASE;
stmt_hdr.standard_opcode_lengths[0] = 0;
stmt_hdr.standard_opcode_lengths[1] = 1;
stmt_hdr.standard_opcode_lengths[2] = 1;
stmt_hdr.standard_opcode_lengths[3] = 1;
stmt_hdr.standard_opcode_lengths[4] = 1;
stmt_hdr.standard_opcode_lengths[5] = 0;
stmt_hdr.standard_opcode_lengths[6] = 0;
stmt_hdr.standard_opcode_lengths[7] = 0;
stmt_hdr.standard_opcode_lengths[8] = 0;
PutInfo( mod->d.d->dasi.addr, (void *) &stmt_hdr,
sizeof( stmt_prologue ) );
mod->d.d->dasi.addr += sizeof( stmt_prologue );
buff = alloca( namelen + 6 );
buff[0] = 0; // no include directories;
memcpy( &buff[1], mod->name, namelen + 1 );
buff[namelen + 2] = 0; // no directory index
buff[namelen + 3] = 0; // no time
buff[namelen + 4] = 0; // no length
buff[namelen + 5] = 0; // no more strings
PutInfo( mod->d.d->dasi.addr, buff, namelen + 6 );
mod->d.d->dasi.addr += namelen + 6;
}
}
}
extern void DwarfGenModule( void )
/********************************/
// write out the addr info, and write out the null die at the end of .debug_info
{
arange_tuple tuple;
unsigned size;
unsigned_8 nulldie;
if( CurrMod->modinfo & MOD_DBI_SEEN )
return;
if( CurrMod->d.d->arange.size > 0 ) { // write out terminator arange
if( FmtData.type & MK_SEGMENTED ) {
size = sizeof( segmented_arange_tuple );
} else {
size = sizeof( flat_arange_tuple );
}
memset( &tuple, 0, size );
PutInfo( CurrMod->d.d->arange.addr, &tuple, size );
}
nulldie = 0;
PutInfo( CurrMod->d.d->pubsym.addr, &nulldie, sizeof( unsigned_8 ) );
}
static void DefAClass( void *_seg )
/*********************************/
{
seg_leader *seg = _seg;
int index;
seg->group = AllocGroup( AutoGrpName, &DBIGroups );
seg->group->grp_addr.seg = 0;
if( SectionTable[SECT_DEBUG_INFO].size > 0 ) {
for( index = 0; index < SECT_NUM_SECTIONS; index++ ) {
if( stricmp( seg->segname, SectionTable[index].name ) == 0 ) {
seg->dbgtype = index + DWARF_DEBUG_INFO;
SectionTable[index].start = seg->size;
break;
}
}
}
}
extern void DwarfDefClass( class_entry *cl, unsigned_32 size )
/************************************************************/
// go through the list of dwarf segments, and make sure VM is allocated for
// all of them.
{
size = size; // to avoid a warning
if( ( cl->flags & CLASS_DEBUG_INFO ) != CLASS_DWARF )
return;
DBIClass = cl;
RingWalk( cl->segs, DefAClass );
}
extern void DwarfAddGlobal( symbol *sym )
/***************************************/
{
sym = sym;
CurrMod->d.d->pubsym.size += strlen( sym->name ) + sizeof( symbol_die ) + 1;
if( FmtData.type & MK_SEGMENTED ) {
CurrMod->d.d->pubsym.size += sizeof( symbol_seg );
}
}
static offset GetLinearGroupOffset( group_entry *group )
/************************************************************/
{
/* gives the absolute offset for ELF, relative for PE and QNX_FLAT;
perhaps PE and QNX_FLAT should be absolute as well if the
DWARF format is changed */
offset off;
if( group != NULL ) {
off = group->linear - group->grp_addr.off;
if( FmtData.type & MK_ELF ) {
off += FmtData.base;
} else {
off -= Groups->linear;
}
}
return( off );
}
extern void DwarfGenGlobal( symbol *sym, section *sect )
/******************************************************/
{
symbol_die die;
symbol_seg symseg;
virt_mem vmem_addr;
size_t len;
sect = sect;
if( !( CurrMod->modinfo & MOD_DBI_SEEN ) ) {
if( ( sym->p.seg == NULL ) || ( sym->p.seg->iscode ) ) {
die.abbrev_code = LABEL_ABBREV_CODE;
} else {
die.abbrev_code = VARIABLE_ABBREV_CODE;
}
vmem_addr = CurrMod->d.d->pubsym.addr;
die.off = sym->addr.off;
if( FmtData.type & ( MK_PE | MK_QNX_FLAT | MK_ELF ) ) {
die.off += GetLinearGroupOffset( sym->p.seg->u.leader->group );
}
die.isexternal = !( sym->info & SYM_STATIC );
PutInfo( vmem_addr, &die, sizeof( symbol_die ) );
vmem_addr += sizeof( symbol_die );
if( FmtData.type & MK_SEGMENTED ) {
symseg.len = 3;
symseg.loc_op = DW_OP_const2u;
symseg.seg = sym->addr.seg;
PutInfo( vmem_addr, &symseg, sizeof( symbol_seg ) );
vmem_addr += sizeof( symbol_seg );
}
len = strlen( sym->name ) + 1;
PutInfo( vmem_addr, sym->name, len );
CurrMod->d.d->pubsym.addr = vmem_addr + len;
}
}
static void DwarfAddLines( segdata *seg, void * lines, unsigned size,
bool is32bit )
/*******************************************************************/
// calculate the amount of space needed to hold all of the line # info.
{
ln_off_pair UNALIGN *lineptr;
unsigned_32 dwsize;
char buff[ 3 + 2 * MAX_LEB128 ];
dw_linenum_delta linedelta;
dw_addr_delta addrdelta;
ln_off_386 prevline;
seg = seg;
lineptr = lines;
prevline.off = 0;
prevline.linnum = 1;
if( FmtData.type & MK_286 ) {
dwsize = 13; // start and end sequence with 16-bit offset
} else {
dwsize = 15; // start and end sequence with 32-bit offset
}
if( !( FmtData.type & MK_SEGMENTED ) ) {
dwsize -= 5; // size of LNE_segment burst
}
while( size > 0 ) {
if( is32bit ) {
linedelta = (signed_32) lineptr->_386.linnum - prevline.linnum;
addrdelta = lineptr->_386.off - prevline.off;
lineptr++;
size -= sizeof( ln_off_386 );
} else {
linedelta = (signed_32) lineptr->_286.linnum - prevline.linnum;
addrdelta = lineptr->_286.off - prevline.off;
lineptr = (void *)( (char *)lineptr + sizeof( ln_off_286 ) );
size -= sizeof( ln_off_286 );
}
prevline.linnum += linedelta;
prevline.off += addrdelta;
dwsize += DWLineGen( linedelta, addrdelta, buff );
}
CurrMod->d.d->dasi.size += dwsize;
}
extern void DwarfGenLines( segdata *seg, void *lines, unsigned size,
bool is32bit )
/******************************************************************/
{
ln_off_pair UNALIGN *lineptr;
unsigned dwsize;
dw_linenum_delta linedelta;
dw_addr_delta addrdelta;
virt_mem vmem_addr;
ln_off_386 prevline;
offset off;
char buff[ 3 + 2 * MAX_LEB128 ];
seg = seg;
if( CurrMod->modinfo & MOD_DBI_SEEN )
return;
prevline.off = 0;
prevline.linnum = 1;
vmem_addr = CurrMod->d.d->dasi.addr;
if( FmtData.type & MK_286 ) {
dwsize = 3;
} else {
dwsize = 5;
}
buff[0] = 0; // extended opcode
buff[1] = dwsize;
buff[2] = DW_LNE_set_address;
if( FmtData.type & MK_286 ) {
*( (unsigned_16 *)&buff[3] ) = seg->a.delta + seg->u.leader->seg_addr.off;
} else {
off = seg->a.delta + seg->u.leader->seg_addr.off;
if( FmtData.type & ( MK_PE | MK_QNX_FLAT | MK_ELF ) ) {
off += GetLinearGroupOffset( seg->u.leader->group );
}
*( (unsigned_32 *)&buff[3] ) = off;
}
dwsize += 2;
PutInfo( vmem_addr, buff, dwsize );
vmem_addr += dwsize;
if( FmtData.type & MK_SEGMENTED ) {
buff[1] = 3;
buff[2] = DW_LNE_set_segment;
*( (unsigned_16 *)&buff[3] ) = seg->u.leader->seg_addr.seg;
PutInfo( vmem_addr, buff, 5 );
vmem_addr += 5;
}
lineptr = (ln_off_pair *) lines;
while( size > 0 ) {
if( is32bit ) {
linedelta = (signed_32) lineptr->_386.linnum - prevline.linnum;
addrdelta = lineptr->_386.off - prevline.off;
lineptr++;
size -= sizeof( ln_off_386 );
} else {
linedelta = (signed_32) lineptr->_286.linnum - prevline.linnum;
addrdelta = lineptr->_286.off - prevline.off;
lineptr = (void *)( (char *)lineptr + sizeof( ln_off_286 ) );
size -= sizeof( ln_off_286 );
}
prevline.linnum += linedelta;
prevline.off += addrdelta;
dwsize = DWLineGen( linedelta, addrdelta, buff );
PutInfo( vmem_addr, buff, dwsize );
vmem_addr += dwsize;
}
buff[0] = 0; // extended opcode
buff[1] = 1; // size 1
buff[2] = DW_LNE_end_sequence;
PutInfo( vmem_addr, buff, 3 );
CurrMod->d.d->dasi.addr = vmem_addr + 3;
}
static void DwarfAddAddrInit( segdata *sdata, void *cookie )
/**********************************************************/
{
sdata = sdata;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?