dftypes.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 794 行 · 第 1/2 页
C
794 行
/******************************************************/
dbg_type ret;
uint class;
if( st->is_struct ){
class = DW_ST_STRUCT;
}else{
class = DW_ST_UNION;
}
ret = DWStruct( Client, class );
st->me = ret;
}
typedef struct {
dw_loc_id locid;
bool addr_seg:1;
bool seg :1;
bool offset :1;
}loc_state;
static dw_loc_id DoLocCnv( dbg_loc loc, loc_state *state ) {
/****************************************/
type_length offset;
dw_loc_id locid;
uint dref_op;
uint size;
dw_sym_handle sym;
if( loc->next != NULL ) {
locid = DoLocCnv( loc->next, state );
}else{
locid = state->locid;
}
switch( loc->class & 0xf0 ) {
case LOC_CONSTANT:
if( loc->class == LOC_MEMORY ) {
sym = (dw_sym_handle)loc->u.fe_sym;
if( state->seg == TRUE ){
DWLocSegment( Client, locid, sym );
}
if( state->offset == TRUE ){
DWLocStatic( Client, locid, sym );
if( state->seg ){
state->addr_seg = TRUE;
}
}
} else {
offset = loc->u.val;
DWLocConstS( Client, locid, offset );
}
break;
case LOC_BP_OFFSET:
offset = NewBase( loc->u.be_sym );
DWLocOp( Client, locid, DW_LOC_fbreg, offset );
break;
case LOC_REG:
DFOutReg( locid, loc->u.be_sym );
break;
case LOC_IND_REG:
if( HW_CEqual( loc->u.be_sym->r.reg, HW_EMPTY ) ) {
//NYI: structured return value on the stack. Have to do something
// suitable. For now, output a no location.
DWLocOp( Client,locid,DW_LOC_breg, 0, 0 );
} else {
DFOutRegInd( locid, loc->u.be_sym );
}
break;
case LOC_OPER:
switch( loc->class & 0x0f ) {
case LOP_IND_2:
case LOP_IND_4:
if( state->addr_seg ){
dref_op = DW_LOC_xderef_size;
}else{
dref_op = DW_LOC_deref_size;
}
if( (loc->class & 0x0f) == LOP_IND_2 ){
size = 2;
}else{
size = 4;
}
DWLocOp( Client, locid, dref_op, size );
state->addr_seg = FALSE; /* ate offset seg */
break;
case LOP_IND_ADDR286:
case LOP_IND_ADDR386:
if( (loc->class & 0x0f) == LOP_IND_ADDR286 ){
size = 2;
}else{
size = 4;
}
if( state->addr_seg ){
dref_op = DW_LOC_xderef_size;
DWLocOp0( Client, locid, DW_LOC_pick ); /* dup seg */
DWLocOp0( Client, locid, DW_LOC_pick ); /* dup offset */
DWLocOp( Client, locid, DW_LOC_plus_uconst, size ); /* seg offset*/
DWLocOp( Client, locid, dref_op, 2 ); /* push seg */
DWLocOp0( Client, locid, DW_LOC_rot ); /* seg at bottom */
DWLocOp( Client, locid, dref_op, size ); /* push offset */
/* now have offset seg on stack */
}else{
dref_op = DW_LOC_deref_size;
DWLocOp0( Client, locid, DW_LOC_dup ); /* dup offset */
DWLocOp( Client, locid, DW_LOC_plus_uconst, size ); /* seg offset*/
DWLocOp( Client, locid, dref_op, 2 ); /* push seg */
DWLocOp0( Client, locid, DW_LOC_swap ); /* get dup offset */
DWLocOp( Client, locid, dref_op, size ); /* push offset */
/* now have offset seg on stack */
}
state->addr_seg = TRUE; /* we have offset seg on stack */
break;
case LOP_ZEB:
DWLocConstU( Client, locid, 0xff );
DWLocOp0( Client, locid, DW_LOC_and );
break;
case LOP_ZEW:
DWLocConstU( Client, locid, 0xffff );
DWLocOp0( Client, locid, DW_LOC_and );
break;
case LOP_MK_FP:
state->addr_seg = TRUE;
break;
case LOP_POP:
DWLocOp0( Client, locid, DW_LOC_drop );
break;
case LOP_XCHG:
DWLocOp0( Client, locid, DW_LOC_swap );
break;
case LOP_ADD:
DWLocOp0( Client, locid, DW_LOC_plus );
break;
case LOP_DUP:
DWLocOp0( Client, locid, DW_LOC_dup );
break;
case LOP_NOP:
DWLocOp0( Client, locid, DW_LOC_not );
break;
}
break;
default:
break;
}
return( locid );
}
static dbg_loc SkipMkFP( dbg_loc loc ) {
/****************************************/
//skip a MkFP and operand
if( (loc->class & 0xf0) == LOC_OPER ) {
if( (loc->class & 0x0f) == LOP_MK_FP ){
loc = loc->next; /* skip MK_FP */
loc = loc->next; /* skip operand */
}
}
return( loc );
}
extern dw_loc_id DBGLoc2DFCont( dbg_loc loc, dw_loc_id df_locid ){
/*****************************************/
/* Convert Brian to a dwarf */
/* in a continious fasion */
/*****************************************/
loc_state state;
state.seg = FALSE;
state.offset = TRUE;
state.addr_seg = FALSE;
state.locid = df_locid;
if( loc != NULL ){
df_locid = DoLocCnv( loc, &state );
}
return( df_locid );
}
extern dw_loc_handle DBGLoc2DF( dbg_loc loc ){
/*****************************************/
/* Convert Brian to a dwarf */
/*****************************************/
dw_loc_id df_locid;
dw_loc_handle df_loc;
loc_state state;
state.seg = FALSE;
state.offset = TRUE;
state.addr_seg = FALSE;
state.locid = DWLocInit( Client );
if( loc != NULL ){
df_locid = DoLocCnv( loc, &state );
df_loc = DWLocFini( Client, df_locid );
}else{
df_locid = state.locid;
df_loc = DWLocFini( Client, df_locid );
}
return( df_loc );
}
extern dw_loc_handle DBGLocBase2DF( dbg_loc loc_seg ){
/*****************************************/
/* Convert Brian to a dwarf */
/*****************************************/
dw_loc_id df_locid;
dw_loc_handle df_loc;
loc_state state;
state.seg = TRUE;
state.offset = TRUE;
state.addr_seg = FALSE;
state.locid = DWLocInit( Client );
loc_seg = SkipMkFP( loc_seg );
if( loc_seg != NULL ){
df_locid = DoLocCnv( loc_seg, &state );
df_loc = DWLocFini( Client, df_locid );
}else{
df_locid = state.locid;
df_loc = DWLocFini( Client, df_locid );
}
return( df_loc );
}
extern dbg_type DFBasedPtr( cg_type ptr_type, dbg_type base,
dbg_loc loc_segment ) {
/****************************************************************/
/* need support to get segment value */
dbg_type ret;
uint flags;
dw_loc_handle dw_segloc;
dw_segloc = DBGLocBase2DF( loc_segment );
flags = DFPtrClass( ptr_type );
ret = DWBasedPointer( Client, base, dw_segloc, flags );
if( dw_segloc != NULL ){
DWLocTrash( Client, dw_segloc );
}
return( ret );
}
static int WVDFAccess( uint attr ){
int ret;
if( attr & FIELD_INTERNAL ){
attr &= ~FIELD_INTERNAL;
ret = DW_FLAG_ARTIFICIAL;
}else{
ret = 0;
}
switch( attr ){
case FIELD_PUBLIC:
ret |= DW_FLAG_PRIVATE;
break;
case FIELD_PROTECTED:
ret |= DW_FLAG_PROTECTED;
break;
case FIELD_PRIVATE:
ret |= DW_FLAG_PRIVATE;
break;
}
return( ret );
}
extern dbg_type DFEndStruct( struct_list *st ) {
/*******************************************************/
field_any *field;
dbg_type ret;
dw_loc_id locid;
dw_loc_handle loc;
char *name;
uint flags;
ret = st->me;
if( st->name[0] != '\0' ){
name = st->name;
}else{
name = NULL;
}
DWBeginStruct( Client, ret, st->size, name, 0, 0 );
for(;;) {
field = st->list;
if( field == NULL ) break;
switch( field->entry.field_type ) {
case FIELD_INHERIT:
flags = WVDFAccess(field->bclass.attr );
loc = DBGLoc2DF( field->bclass.u.adjustor );
DBLocFini( field->bclass.u.adjustor );
if( field->bclass.kind == INHERIT_VBASE ){
flags |= DW_FLAG_VIRTUAL;
}
DWAddInheritance( Client, field->bclass.base, loc, flags );
DWLocTrash( Client, loc );
break;
case FIELD_METHOD:
DBLocFini( field->method.u.loc );
break;
case FIELD_NESTED:
break;
case FIELD_LOC:
case FIELD_OFFSET:
/* some loc thing */
flags = WVDFAccess(field->member.attr );
if( field->entry.field_type == FIELD_LOC ){
loc = DBGLoc2DF( field->member.u.loc );
DBLocFini( field->member.u.loc );
}else{
locid = DWLocInit( Client );
DWLocConstU( Client, locid, field->member.u.off );
DWLocOp0( Client, locid, DW_LOC_plus );
loc = DWLocFini( Client, locid );
}
if( field->member.b_strt == 0 && field->member.b_len == 0 ){
DWAddField( Client, field->member.base, loc,
field->member.name, flags );
}else{
int bit_start;
bit_start = 4*8-( field->member.b_strt+field->member.b_len);
DWAddBitField( Client, field->member.base, loc, 4,
bit_start, field->member.b_len,
field->member.name, flags );
}
DWLocTrash( Client, loc );
break;
case FIELD_STFIELD:
/* some loc thing */
flags = WVDFAccess( field->stfield.attr );
loc = DBGLoc2DF( field->stfield.loc );
DBLocFini( field->stfield.loc );
DWAddField( Client, field->stfield.base, loc,
field->stfield.name, flags | DW_FLAG_STATIC );
DWLocTrash( Client, loc );
break;
}
st->list = field->entry.next;
_Free( field, sizeof( field_entry ) );
}
DWEndStruct( Client );
return( ret );
}
extern dbg_type DFEndEnum( enum_list *en ) {
/**************************************************/
dbg_type ret;
type_def *tipe_addr;
const_entry *cons;
signed_64 val;
tipe_addr = TypeAddress( en->tipe );
ret = DWBeginEnumeration( Client, tipe_addr->length, NULL, 0, 0 );
for(;;) {
cons = en->list;
if( cons == NULL ) break;
val = cons->val;
if( val.u._32[I64HI32] == 0 || val.u._32[I64HI32] == -1 ){
DWAddConstant( Client, val.u._32[I64LO32], cons->name );
}else{
DWAddConstant( Client, val.u._32[I64LO32], cons->name );
}
en->list = cons->next;
_Free( cons, sizeof( const_entry ) + cons->len );
}
DWEndEnumeration( Client );
return( ret );
}
extern dbg_type DFEndProc( proc_list *pr ) {
/***************************************************/
parm_entry *parm;
dbg_type proc_type;
uint flags;
// flags = DFPtrClass( pr->call );
flags = DW_FLAG_PROTOTYPED | DW_FLAG_DECLARATION;
proc_type = DWBeginSubroutineType( Client, pr->ret, NULL, 0, flags );
parm = pr->list;
if( parm == NULL ){
DWAddEllipsisToSubroutineType( Client );
}
for(;;) {
if( parm == NULL ) break;
DWAddParmToSubroutineType( Client, parm->tipe, NULL, NULL, NULL );
pr->list = parm->next;
_Free( parm, sizeof( parm_entry ) );
parm = pr->list;
}
DWEndSubroutineType( Client );
return( proc_type );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?