static bool dirFuncSpace( directive_t *dir, dir_table_enum parm ) //*************************************************************** { dir_operand *dirop; int_32 count; /* unused parameters */ (void)parm; if( !dirNumOperandsVerify( dir->num_operands, 1 ) ) { return( true ); } dirop = dir->operand_list; assert( dirop->type == DIROP_INTEGER ); count = NUMBER_INTEGER( dirop ); if( count < 0 ) { Error( OP_OUT_OF_RANGE, 0 ); return( true ); } #ifdef _STANDALONE_ ObjNullPad( CurrentSection, (uint_8)count ); #else ObjNullPad( (uint_8)count ); #endif return( true ); }
static bool dirFuncStorageAlloc( directive_t *dir, dir_table_enum parm ) //********************************************************************** // e.g.) .comm name, expr // Emit a label name, then emit expr bytes of data { dir_operand *dirop; sym_handle sym; int_32 expr; char *buffer; owl_section_handle curr_section; reserved_section as_section = 0; if( !dirNumOperandsVerify( dir->num_operands, 2 ) ) { return( TRUE ); } dirop = dir->operand_list; if( dirop->type != DIROP_SYMBOL ) { Error( IMPROPER_DIROP, 0 ); return( TRUE ); } sym = SYMBOL_HANDLE( dirop ); dirop = dirop->next; if( dirop->type != DIROP_INTEGER ) { Error( IMPROPER_DIROP, 1 ); return( TRUE ); } expr = NUMBER_INTEGER( dirop ); if( expr <= 0 ) { Error( OP_OUT_OF_RANGE, 1 ); return( TRUE ); } if( ObjLabelDefined( sym ) ) { // then such label has already been emitted Error( SYM_ALREADY_DEFINED, SymName( sym ) ); return( TRUE ); } curr_section = CurrentSection; switch( parm ) { case DT_SEC_DATA: // .comm => globl as_section = AS_SECTION_DATA; SymSetLinkage( sym, SL_GLOBAL ); break; case DT_SEC_BSS: // .lcomm, .bss as_section = AS_SECTION_BSS; break; default: assert( FALSE ); } ObjSwitchSection( as_section ); // Have to switch to the right ObjEmitLabel( sym ); // section before emitting label. buffer = MemAlloc( expr ); memset( buffer, 0, expr ); ObjEmitData( CurrentSection, buffer, expr, TRUE ); // Align the data also. MemFree( buffer ); CurrentSection = curr_section; // Switch back to where you were. return( TRUE ); }
static bool dirFuncAlign ( directive_t *dir, dir_table_enum parm ) //**************************************************************** { int_32 val; parm = parm; if( !dirNumOperandsVerify( dir->num_operands, 1 ) ) { return( TRUE ); } assert( dir->operand_list->type == DIROP_INTEGER ); val = NUMBER_INTEGER( dir->operand_list ); if( val < 0 || val > MAX_ALIGNMENT ) { Error( OP_OUT_OF_RANGE, 0 ); return( TRUE ); } autoAlignment = FALSE; CurrAlignment = val; return( TRUE ); }
static bool dirFuncValues( directive_t *dir, dir_table_enum parm ) //**************************************************************** { dir_operand *dirop; static int_8 byte; static int_16 half; static int_32 word; static signed_64 quad; static float flt; static double dbl; int_32 rep; uint_8 prev_alignment = 0; int opnum; void *target = NULL; owl_reloc_type rtype = 0; struct { int size; void *ptr; uint_8 alignment; } data_table[] = { { 1, &byte, 0 }, // DT_VAL_INT8 { 8, &dbl, 3 }, // DT_VAL_DOUBLE { 4, &flt, 2 }, // DT_VAL_FLOAT { 2, &half, 1 }, // DT_VAL_INT16 { 4, &word, 2 }, // DT_VAL_INT32 { 8, &quad, 3 }, // DT_VAL_INT64 }; #define TABLE_IDX( x ) ( ( x ) - DT_VAL_FIRST ) #ifdef _STANDALONE_ if( OWLTellSectionType( CurrentSection ) & OWL_SEC_ATTR_BSS ) { Error( INVALID_BSS_DIRECTIVE, SymName( dir->dir_sym ) ); return( TRUE ); } #endif if( autoAlignment ) { prev_alignment = CurrAlignment; CurrAlignment = data_table[TABLE_IDX(parm)].alignment; } dirop = dir->operand_list; opnum = 0; while( dirop ) { rep = 1; switch( parm ) { case DT_VAL_INT8: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT ); if( dirop->type == DIROP_INTEGER ) { byte = (int_8)NUMBER_INTEGER( dirop ); } else { // repeat rep = REPEAT_COUNT( dirop ); byte = (int_8)REPEAT_INTEGER( dirop ); } break; case DT_VAL_INT64: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT ); if( dirop->type == DIROP_INTEGER ) { quad.u._32[I64LO32] = NUMBER_INTEGER( dirop ); } else { // repeat rep = REPEAT_COUNT( dirop ); quad.u._32[I64LO32] = REPEAT_INTEGER( dirop ); } break; case DT_VAL_DOUBLE: assert( dirop->type == DIROP_FLOATING || dirop->type == DIROP_REP_FLT ); if( dirop->type == DIROP_FLOATING ) { dbl = NUMBER_FLOAT( dirop ); } else { rep = REPEAT_COUNT( dirop ); dbl = REPEAT_FLOAT( dirop ); } break; case DT_VAL_FLOAT: assert( dirop->type == DIROP_FLOATING || dirop->type == DIROP_REP_FLT ); if( dirop->type == DIROP_FLOATING ) { flt = (float)NUMBER_FLOAT( dirop ); } else { rep = REPEAT_COUNT( dirop ); flt = (float)REPEAT_FLOAT( dirop ); } break; case DT_VAL_INT32: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT || dirop->type == DIROP_SYMBOL || dirop->type == DIROP_NUMLABEL_REF ); if( dirop->type == DIROP_INTEGER ) { word = NUMBER_INTEGER( dirop ); } else if( dirop->type == DIROP_REP_INT ) { rep = REPEAT_COUNT( dirop ); word = REPEAT_INTEGER( dirop ); } else { // reloc word = SYMBOL_OFFSET( dirop ); if( assignRelocType( &rtype, SYMBOL_RELOC_TYPE( dirop ), parm ) ) { if( dirop->type == DIROP_SYMBOL ) { target = SymName( SYMBOL_HANDLE( dirop ) ); } else { assert( dirop->type == DIROP_NUMLABEL_REF ); target = &SYMBOL_LABEL_REF( dirop ); } } else { Error( IMPROPER_DIROP, opnum ); } } break; case DT_VAL_INT16: assert( dirop->type == DIROP_INTEGER || dirop->type == DIROP_REP_INT || dirop->type == DIROP_SYMBOL || dirop->type == DIROP_NUMLABEL_REF ); if( dirop->type == DIROP_INTEGER ) { half = (int_16)NUMBER_INTEGER( dirop ); } else if( dirop->type == DIROP_REP_INT ) { rep = REPEAT_COUNT( dirop ); half = (int_16)REPEAT_INTEGER( dirop ); } else { // reloc half = (int_16)SYMBOL_OFFSET( dirop ); if( assignRelocType( &rtype, SYMBOL_RELOC_TYPE( dirop ), parm ) ) { if( dirop->type == DIROP_SYMBOL ) { target = SymName( SYMBOL_HANDLE( dirop ) ); } else { assert( dirop->type == DIROP_NUMLABEL_REF ); target = &SYMBOL_LABEL_REF( dirop ); } } else { Error( IMPROPER_DIROP, opnum ); } } break; default: Error( INTERNAL_UNKNOWN_DT_PARM, parm ); return( FALSE ); } if( target != NULL ) { assert( (parm == DT_VAL_INT32 || parm == DT_VAL_INT16) && rep == 1 ); #ifdef _STANDALONE_ // align with data ObjEmitReloc( CurrentSection, target, rtype, ( opnum == 0 ), (dirop->type == DIROP_SYMBOL) ); #else // align with data ObjEmitReloc( target, rtype, ( opnum == 0 ), (dirop->type == DIROP_SYMBOL ) ); #endif target = NULL; } #ifdef _STANDALONE_ // only align for the first data operand ObjEmitData( CurrentSection, data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size, ( opnum == 0 ) ); #else // only align for the first data operand ObjEmitData( data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size, ( opnum == 0 ) ); #endif for( rep--; rep > 0; rep-- ) { #ifdef _STANDALONE_ OWLEmitData( CurrentSection, data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size ); #else ObjDirectEmitData( data_table[TABLE_IDX(parm)].ptr, data_table[TABLE_IDX(parm)].size ); #endif #if 0 printf( "Size=%d\n", data_table[TABLE_IDX(parm)].size ); switch( parm ) { case DT_VAL_INT8: printf( "Out->%d\n", *(int_8 *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_DOUBLE: printf( "Out->%lf\n", *(double *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_FLOAT: printf( "Out->%f\n", *(float *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_INT16: printf( "Out->%d\n", *(int_16 *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_INT32: printf( "Out->%d\n", *(int_32 *)(data_table[TABLE_IDX(parm)].ptr) ); break; case DT_VAL_INT64: printf( "Out->%d\n", ((signed_64 *)(data_table[TABLE_IDX(parm)].ptr))->_32[0] ); break; default: assert( FALSE ); } #endif } opnum++; dirop = dirop->next; } if( autoAlignment ) { CurrAlignment = prev_alignment; } return( TRUE ); }