static void registerSegment( orl_sec_handle o_shnd ) //************************************************** { orl_sec_flags sec_flags; orl_sec_handle reloc_section; orl_sec_alignment alignment; char * content; int ctr; segment *seg; seg = NewSegment(); seg->name = ORLSecGetName( o_shnd ); seg->size = ORLSecGetSize( o_shnd ); seg->start = 0; seg->use_32 = 1; // only 32-bit object files use ORL seg->attr = ( 2 << 2 ); // (?) combine public alignment = ORLSecGetAlignment( o_shnd ); // FIXME: Need better alignment translation. switch( alignment ) { case 0: seg->attr |= ( 1 << 5 ); break; case 1: seg->attr |= ( 2 << 5 ); break; case 3: case 4: seg->attr |= ( 3 << 5 ); break; case 8: seg->attr |= ( 4 << 5 ); break; case 2: seg->attr |= ( 5 << 5 ); break; case 12: seg->attr |= ( 6 << 5 ); break; default: // fprintf( stderr, "NOTE! 'Strange' alignment (%d) found. Using byte alignment.\n", alignment ); seg->attr |= ( 1 << 5 ); break; } sec_flags = ORLSecGetFlags( o_shnd ); if( !( sec_flags & ORL_SEC_FLAG_EXEC ) ) { seg->data_seg = true; } if( seg->size > 0 && ORLSecGetContents( o_shnd, &content ) == ORL_OKAY ) { Segment = seg; // Putting contents into segment struct. for( ctr = 0; ctr < seg->size; ctr++ ) { PutSegByte( ctr, content[ctr] ); } } if( !HashTableInsert( SectionToSegmentTable, (hash_value)o_shnd, (hash_data)seg ) ) { SysError( ERR_OUT_OF_MEM, false ); } reloc_section = ORLSecGetRelocTable( o_shnd ); if( reloc_section ) { if( !addRelocSection( reloc_section ) ) { SysError( ERR_OUT_OF_MEM, false ); } } }
static void printMasmHeader( section_ptr sec ) { orl_sec_alignment alignment; orl_sec_flags flags; orl_sec_type type; orl_sec_frame frame; orl_sec_combine combine; orl_sec_size size; char *name; char *class; char *gname; char *astr; orl_sec_handle sh; orl_group_handle grp = NULL; char comname[ MAX_LINE_LEN ]; size = ORLSecGetSize( sec->shnd ); // Load all necessary information name = sec->name; if( !name ) { name = ""; } type = ORLSecGetType( sec->shnd ); flags = ORLSecGetFlags( sec->shnd ); frame = ORLSecGetAbsFrame( sec->shnd ); if( DFormat & DFF_ASM ) { class = ORLSecGetClassName( sec->shnd ); if( !class ) { class = ""; } if( flags & ORL_SEC_FLAG_COMDAT ) { BufferConcat( "; ERROR: Comdat symbols cannot be assembled." ); } else if( frame == ORL_SEC_NO_ABS_FRAME ) { alignment = ORLSecGetAlignment( sec->shnd ); combine = ORLSecGetCombine( sec->shnd ); BufferQuoteName( name ); BufferStore( "\t\tSEGMENT\t%s %s %s '%s'", getAlignment( alignment ), getCombine( combine ), getUse( flags ), class ); } else {
static orl_return DeclareSegment( orl_sec_handle sec ) /****************************************************/ // declare the "segment" { segdata *sdata; segnode *snode; char *name; unsigned_32 _WCUNALIGNED *contents; size_t len; orl_sec_flags flags; orl_sec_type type; unsigned numlines; unsigned segidx; type = ORLSecGetType( sec ); if( type != ORL_SEC_TYPE_NO_BITS && type != ORL_SEC_TYPE_PROG_BITS ) { return( ORL_OKAY ); } flags = ORLSecGetFlags( sec ); name = ORLSecGetName( sec ); sdata = AllocSegData(); segidx = ORLCvtSecHdlToIdx( sec ); snode = AllocNodeIdx( SegNodes, segidx ); snode->entry = sdata; snode->handle = sec; sdata->iscdat = (flags & ORL_SEC_FLAG_COMDAT) != 0; len = sizeof( CoffIDataSegName ) - 1; if( strnicmp( CoffIDataSegName, name, len ) == 0 ) { SeenDLLRecord(); CurrMod->modinfo |= MOD_IMPORT_LIB; if( name[len + 1] == '6' ) { // it is the segment containg the name ORLSecGetContents( sec, (unsigned_8 **)&ImpExternalName ); ImpExternalName += 2; } else if( name[len + 1] == '4' ) { // it is an import by ordinal ORLSecGetContents( sec, (void *) &contents ); ImpOrdinal = *contents; } sdata->isdead = true; sdata->isidata = true; } sdata->combine = COMBINE_ADD; if( flags & ORL_SEC_FLAG_NO_PADDING ) { sdata->align = 0; } else { sdata->align = ORLSecGetAlignment( sec ); } sdata->is32bit = true; sdata->length = ORLSecGetSize( sec ); sdata->u.name = name; if( flags & ORL_SEC_FLAG_EXEC ) { sdata->iscode = true; } else if( flags & ORL_SEC_FLAG_UNINITIALIZED_DATA ) { sdata->isuninit = true; #ifdef _DEVELOPMENT } else { unsigned namelen; namelen = strlen(name); if( namelen >= 3 && memicmp(name + namelen - 3, "bss", 3) == 0 ) { LnkMsg( ERR+MSG_INTERNAL, "s", "Initialized BSS found" ); } #endif } numlines = ORLSecGetNumLines( sec ); if( numlines > 0 ) { numlines *= sizeof(orl_linnum); DBIAddLines( sdata, ORLSecGetLines( sec ), numlines, true ); } return( ORL_OKAY ); }
return_val DoPass1( orl_sec_handle shnd, unsigned_8 *contents, orl_sec_size size, ref_list sec_ref_list, scantab_ptr stl ) // perform pass 1 on one section { orl_sec_offset loop; dis_dec_ins decoded; dis_value value; dis_return dr; unnamed_label_return_struct rs; return_val error; unsigned i; ref_entry r_entry; dis_inst_flags flags; orl_sec_offset op_pos; int is_intel; int adjusted; sa_disasm_struct sds; sds.data = contents; sds.last = size - 1; if( sec_ref_list != NULL ) { r_entry = sec_ref_list->first; } else { r_entry = NULL; } flags.u.all = DIF_NONE; if( GetMachineType() == ORL_MACHINE_TYPE_I386 ) { if( ( GetFormat() != ORL_OMF ) || ( ORLSecGetFlags( shnd ) & ORL_SEC_FLAG_USE_32 ) ) { flags.u.x86 = DIF_X86_USE32_FLAGS; } is_intel = 1; } else { is_intel = IsIntelx86(); } for( loop = 0; loop < size; loop += decoded.size ) { // skip data in code segment while( stl && ( loop > stl->end ) ) { stl = stl->next; } if( stl && ( loop >= stl->start ) ) { decoded.size = 0; if( is_intel ) { r_entry = DoPass1Relocs( contents, r_entry, loop, stl->end ); } loop = stl->end; stl = stl->next; continue; } // data may not be listed in scan table, but a fixup at this offset will // give it away while( r_entry && ( ( r_entry->offset < loop ) || SkipRef(r_entry) ) ) { r_entry = r_entry->next; } if( r_entry && ( r_entry->offset == loop ) ) { if( is_intel || IsDataReloc( r_entry ) ) { // we just skip the data op_pos = loop; decoded.size = 0; loop += RelocSize( r_entry ); r_entry = DoPass1Relocs( contents, r_entry, op_pos, loop ); continue; } } DisDecodeInit( &DHnd, &decoded ); decoded.flags.u.all |= flags.u.all; sds.offs = loop; dr = DisDecode( &DHnd, &sds, &decoded ); // if an invalid instruction was found, there is nothing we can do. if( dr != DR_OK ) return( RC_ERROR ); for( i = 0; i < decoded.num_ops; ++i ) { adjusted = 0; op_pos = loop + decoded.op[i].op_position; switch( decoded.op[i].type & DO_MASK ) { case DO_IMMED: if( !is_intel ) break; /* fall through */ case DO_RELATIVE: case DO_MEMORY_REL: if( ( decoded.op[i].type & DO_MASK ) != DO_IMMED ) { decoded.op[i].value += loop; adjusted = 1; } /* fall through */ case DO_ABSOLUTE: case DO_MEMORY_ABS: // Check for reloc at this location while( r_entry && r_entry->offset < op_pos ) { r_entry = r_entry->next; } if( r_entry && ( r_entry->offset == op_pos ) ) { if( is_intel && r_entry->label->shnd && ( r_entry->type != ORL_RELOC_TYPE_SEGMENT ) && ( r_entry->label->type == LTYP_SECTION ) ) { /* For section offsets under intel we MUST generate a * local label because the offset might change when the * code is re-assembled */ if( r_entry->addend ) { r_entry->no_val = 0; CreateUnnamedLabel( r_entry->label->shnd, HandleAddend( r_entry ), &rs ); } else { r_entry->no_val = 1; if( adjusted && isSelfReloc( r_entry ) && ( r_entry->label->type == LTYP_SECTION ) ) { /* This is a kludgy reloc done under OMF */ decoded.op[i].value -= loop; decoded.op[i].value -= decoded.size; switch( RelocSize( r_entry ) ) { case( 2 ): decoded.op[i].value = (uint_16)(decoded.op[i].value); case( 1 ): decoded.op[i].value = (uint_8)(decoded.op[i].value); } } value = decoded.op[i].value; if( value < 0 || value > ORLSecGetSize( r_entry->label->shnd ) ) { // can't fold it into the label position - BBB Oct 28, 1996 value = 0; r_entry->no_val = 0; } CreateUnnamedLabel( r_entry->label->shnd, value, &rs ); } if( rs.error != RC_OKAY ) return( rs.error ); r_entry->label = rs.entry; } else { // fixme: got to handle other types of relocs here } } else if( ( decoded.op[i].type & DO_MASK ) != DO_IMMED ) { if( decoded.op[i].base == DR_NONE && decoded.op[i].index == DR_NONE ) { switch( decoded.op[i].type & DO_MASK ) { case DO_MEMORY_REL: case DO_MEMORY_ABS: // use decoded instruction size for absolute memory on amd64. // the cpu will reference rip _after_ the instruction is // completely fetched and decoded. // relocations in pass2 are not applied because they break // relative memory references if no relocation is present! if( GetMachineType() == ORL_MACHINE_TYPE_AMD64 ) { decoded.op[i].value += decoded.size; // I don't know if this is neccessary, but it will generate // labels for memory references if no symbol is present // (ex: executable file) CreateUnnamedLabel( shnd, decoded.op[i].value, &rs ); if( rs.error != RC_OKAY ) return( rs.error ); error = CreateUnnamedLabelRef( shnd, rs.entry, op_pos ); } else { // create an LTYP_ABSOLUTE label CreateAbsoluteLabel( shnd, decoded.op[i].value, &rs ); if( rs.error != RC_OKAY ) return( rs.error ); error = CreateAbsoluteLabelRef( shnd, rs.entry, op_pos ); } break; default: // create an LTYP_UNNAMED label CreateUnnamedLabel( shnd, decoded.op[i].value, &rs ); if( rs.error != RC_OKAY ) return( rs.error ); error = CreateUnnamedLabelRef( shnd, rs.entry, op_pos ); break; } if( error != RC_OKAY ) { return( error ); } } } break; } } } return( RC_OKAY ); }
num_errors DoPass2( section_ptr sec, unsigned_8 *contents, orl_sec_size size, label_list sec_label_list, ref_list sec_ref_list ) // perform pass 2 on one section { struct pass2 data; label_entry l_entry; dis_dec_ins decoded; char name[ MAX_INS_NAME ]; char ops[ MAX_OBJ_NAME + 24 ]; // at most 1 label/relocation per instruction, plus room for registers, brackets and other crap dis_inst_flags flags; scantab_ptr st; int is_intel; sa_disasm_struct sds; char *FPU_fixup; int pos_tabs; bool is32bit; routineBase = 0; st = sec->scan; data.size = size; sds.data = contents; sds.last = size - 1; l_entry = NULL; if( sec_label_list != NULL ) { l_entry = sec_label_list->first; } if( sec_ref_list != NULL ) { data.r_entry = sec_ref_list->first; } else { data.r_entry = NULL; } data.disassembly_errors = 0; if( source_mix ) { GetSourceFile( sec ); } PrintHeader( sec ); if( size && sec_label_list ) PrintAssumeHeader( sec ); flags.u.all = DIF_NONE; if( GetMachineType() == ORL_MACHINE_TYPE_I386 ) { if( ( GetFormat() != ORL_OMF ) || ( ORLSecGetFlags( sec->shnd ) & ORL_SEC_FLAG_USE_32 ) ) { flags.u.x86 = DIF_X86_USE32_FLAGS; } is_intel = 1; } else { is_intel = IsIntelx86(); } is32bit = ( size >= 0x10000 ); for( data.loop = 0; data.loop < size; data.loop += decoded.size ) { // process data in code segment while( st && ( data.loop > st->end ) ) { st = st->next; } if( st && ( data.loop >= st->start ) ) { decoded.size = 0; processDataInCode( sec, contents, &data, st->end - data.loop, &l_entry ); st = st->next; continue; } // data may not be listed in scan table, but a fixup at this offset will // give it away while( data.r_entry && ( data.r_entry->offset < data.loop ) ) { data.r_entry = data.r_entry->next; } FPU_fixup = processFpuEmulatorFixup( &data.r_entry, data.loop ); if( data.r_entry && ( data.r_entry->offset == data.loop ) ) { if( is_intel || IsDataReloc( data.r_entry ) ) { // we just skip the data decoded.size = 0; processDataInCode( sec, contents, &data, RelocSize( data.r_entry ), &l_entry ); continue; } } if( source_mix ) { MixSource( data.loop ); } DisDecodeInit( &DHnd, &decoded ); decoded.flags.u.all |= flags.u.all; sds.offs = data.loop; DisDecode( &DHnd, &sds, &decoded ); if( sec_label_list ) { l_entry = handleLabels( sec->name, data.loop, data.loop + decoded.size, l_entry, size ); if( ( l_entry != NULL ) && ( l_entry->offset > data.loop ) && ( l_entry->offset < data.loop + decoded.size ) ) { /* If we have a label planted in the middle of this instruction (see inline memchr for example), put out a couple of data bytes, and then restart decode and label process from offset of actual label. */ decoded.size = 0; processDataInCode( sec, contents, &data, l_entry->offset - data.loop, &l_entry ); continue; } } DisFormat( &DHnd, &data, &decoded, DFormat, name, sizeof( name ), ops, sizeof( ops ) ); if( FPU_fixup != NULL ) { if( !(DFormat & DFF_ASM) ) { BufferAlignToTab( PREFIX_SIZE_TABS ); } BufferStore( "\t%sFPU fixup %s\n", CommentString, FPU_fixup ); } if( !(DFormat & DFF_ASM) ) { unsigned_64 *tmp_64; unsigned_32 *tmp_32; unsigned_16 *tmp_16; tmp_64 = (unsigned_64 *)(contents + data.loop); tmp_32 = (unsigned_32 *)(contents + data.loop); tmp_16 = (unsigned_16 *)(contents + data.loop); if( DHnd.need_bswap ) { switch( DisInsSizeInc( &DHnd ) ) { //case 8: SWAP_64( *tmp_64 ); // break; case 4: SWAP_32( *tmp_32 ); break; case 2: SWAP_16( *tmp_16 ); break; default: break; } } PrintLinePrefixAddress( data.loop, is32bit ); PrintLinePrefixData( contents, data.loop, size, DisInsSizeInc( &DHnd ), decoded.size ); BufferAlignToTab( PREFIX_SIZE_TABS ); } BufferStore( "\t%s", name ); if( *ops != '\0' ) { pos_tabs = ( DisInsNameMax( &DHnd ) + TAB_WIDTH ) / TAB_WIDTH + 1; if( !(DFormat & DFF_ASM) ) { pos_tabs += PREFIX_SIZE_TABS; } BufferAlignToTab( pos_tabs ); BufferConcat( ops ); } BufferConcatNL(); BufferPrint(); } if( sec_label_list ) { l_entry = handleLabels( sec->name, size, (orl_sec_offset)-1, l_entry, size ); } if( !(DFormat & DFF_ASM) ) { routineSize = data.loop - routineBase; BufferConcatNL(); BufferMsg( ROUTINE_SIZE ); BufferStore(" %d ", routineSize ); BufferMsg( BYTES ); BufferConcat(", "); BufferMsg( ROUTINE_BASE ); BufferStore(" %s + %04X\n\n", sec->name, routineBase ); BufferPrint(); } if( source_mix ) { EndSourceMix(); } PrintTail( sec ); return( data.disassembly_errors ); }
orl_return PrintSecInfo( orl_sec_handle o_shnd ) /**********************************************/ { char *buf; int loop; int loop2; orl_sec_size size; orl_sec_type sec_type; orl_sec_flags sec_flags; orl_sec_handle reloc_section; orl_sec_handle symbol_table; orl_sec_handle string_table; int sep; int segname_printed = 0; size = 0; // just because gcc is a little retarded sectionFound = 1; if( dump.sections || dump.sec_contents ) { buf = ORLSecGetName( o_shnd ); printf( "[%s]\n", buf ); segname_printed = 1; size = ORLSecGetSize( o_shnd ); } if( dump.sections ) { //printf( "\nSection Handle:\t0x%x\n", o_shnd ); printf( "Size=%8.8x ", size ); sec_type = ORLSecGetType( o_shnd ); printf( "Align=%4.4x ", ORLSecGetAlignment( o_shnd ) ); //printf( "Section Type:\t%d\n", sec_type ); printf( "(" ); switch( sec_type ) { case ORL_SEC_TYPE_NONE: printf( "sec_type_none" ); break; case ORL_SEC_TYPE_NO_BITS: printf( "no bits" ); break; case ORL_SEC_TYPE_PROG_BITS: printf( "program bits" ); break; case ORL_SEC_TYPE_SYM_TABLE: printf( "symbol table" ); break; case ORL_SEC_TYPE_DYN_SYM_TABLE: printf( "dynamic symbol table" ); break; case ORL_SEC_TYPE_STR_TABLE: printf( "string table" ); break; case ORL_SEC_TYPE_RELOCS: printf( "relocs" ); break; case ORL_SEC_TYPE_RELOCS_EXPADD: printf( "relocs with explicit addends" ); break; case ORL_SEC_TYPE_HASH: printf( "hash table" ); break; case ORL_SEC_TYPE_DYNAMIC: printf( "dynamic linking information" ); break; case ORL_SEC_TYPE_NOTE: printf( "note or comment" ); break; default: printf( "unknown type? %s", sec_type ); break; } printf( ") " ); sec_flags = ORLSecGetFlags( o_shnd ); printf( "ORL_flags=0x%x\n", sec_flags ); sep = 0; if( sec_flags ) printf( " " ); if( sec_flags & ORL_SEC_FLAG_EXEC ) { printf( "executable code" ); sep++; } if( sec_flags & ORL_SEC_FLAG_INITIALIZED_DATA ) { if( sep++ ) printf( ", " ); printf( "initialized data" ); } if( sec_flags & ORL_SEC_FLAG_UNINITIALIZED_DATA ) { if( sep++ ) printf( ", " ); printf( "uninitialized data" ); } if( sec_flags & ORL_SEC_FLAG_GROUPED ) { if( sep++ ) printf( ", " ); printf( "grouped section" ); } if( sec_flags & ORL_SEC_FLAG_NO_PADDING ) { if( sep++ ) printf( ", " ); printf( "no padding to next boundary" ); } if( sec_flags & ORL_SEC_FLAG_OVERLAY ) { if( sep++ ) printf( ", " ); printf( "contains an overlay" ); } if( sec_flags & ORL_SEC_FLAG_REMOVE ) { if( sep++ ) printf( ", " ); printf( "remove at link-time" ); } if( sec_flags & ORL_SEC_FLAG_COMDAT ) { if( sep++ ) printf( ", " ); printf( "communal data" ); } if( sec_flags & ORL_SEC_FLAG_DISCARDABLE ) { if( sep++ ) printf( ", " ); printf( "discardable" ); } if( sec_flags & ORL_SEC_FLAG_NOT_CACHED ) { if( sep++ ) printf( ", " ); printf( "cannot be cached" ); } if( sec_flags & ORL_SEC_FLAG_NOT_PAGEABLE) { if( sep++ ) printf( ", " ); printf( "not pageable" ); } if( sec_flags & ORL_SEC_FLAG_SHARED ) { if( sep++ ) printf( ", " ); printf( "shared in memory" ); } if( sec_flags & ORL_SEC_FLAG_EXECUTE_PERMISSION ) { if( sep++ ) printf( ", " ); printf( "execute permission" ); } if( sec_flags & ORL_SEC_FLAG_READ_PERMISSION ) { if( sep++ ) printf( ", " ); printf( "read permission" ); } if( sec_flags & ORL_SEC_FLAG_WRITE_PERMISSION) { if( sep++ ) printf( ", " ); printf( "write permission" ); } if( sep ) printf( "\n" ); } if( dump.sec_contents ) { if( ORLSecGetContents( o_shnd, (unsigned_8 **)&buf ) == ORL_OKAY ) { printf( "Contents:\n" ); for( loop = 0; loop < size; loop += 16 ) { printf( "0x%8.8x: ", loop ); for( loop2 = 0; loop2 < 16; loop2++ ) { if( loop + loop2 < size ) { printf( "%2.2x ", buf[loop+loop2] ); } else { printf( " " ); } if( loop2 == 7 ) { printf( " " ); } } printf( " " ); for( loop2 = 0; loop2 < 16 && loop + loop2 < size; loop2++ ) { if( buf[loop+loop2] >= 32 && buf[loop+loop2] <= 122 ) { printf( "%c", buf[loop+loop2] ); } else { printf( "." ); } if( loop2 == 7 ) { printf( " " ); } } printf( "\n" ); } } } if( dump.relocs ) { reloc_section = ORLSecGetRelocTable( o_shnd ); if( reloc_section ) { if( !segname_printed++ ) { buf = ORLSecGetName( o_shnd ); printf( "[%s]\n", buf ); } printf( "Relocs in [%s], ", ORLSecGetName( reloc_section ) ); symbol_table = ORLSecGetSymbolTable( reloc_section ); if( symbol_table ) { printf( "symtab='%s', ", ORLSecGetName( symbol_table ) ); string_table = ORLSecGetStringTable( symbol_table ); if( string_table ) { printf( "strtab='%s'.\n", ORLSecGetName( string_table ) ); } else { printf( "strtab=none.\n" ); } } else { printf( "symtab=none, strtab=none.\n" ); } //printf( "Relocs:\n" ); ORLRelocSecScan( reloc_section, &PrintRelocInfo ); } } return( ORL_OKAY ); }
static void printUnixHeader( section_ptr sec ) { orl_sec_alignment alignment; orl_sec_flags flags; orl_sec_type type; char attributes[10]; char * ca; alignment = ORLSecGetAlignment( sec->shnd ); type = ORLSecGetType( sec->shnd ); flags = ORLSecGetFlags( sec->shnd ); ca = attributes; if( !(Options & METAWARE_COMPATIBLE) ) { if( (flags & ORL_SEC_FLAG_EXEC) || sec->type == SECTION_TYPE_TEXT ) { *ca++ = 'c'; } if( (flags & ORL_SEC_FLAG_INITIALIZED_DATA) || sec->type == SECTION_TYPE_DATA || sec->type == SECTION_TYPE_PDATA ) { *ca++ = 'd'; } if( (flags & ORL_SEC_FLAG_UNINITIALIZED_DATA) || sec->type == SECTION_TYPE_BSS ) { *ca++ = 'u'; } if( (type == ORL_SEC_TYPE_NOTE) || sec->type == SECTION_TYPE_DRECTVE ) { *ca++ = 'i'; } if( flags & ORL_SEC_FLAG_DISCARDABLE ) { *ca++ = 'n'; } if( flags & ORL_SEC_FLAG_REMOVE ) { *ca++ = 'R'; } if( flags & ORL_SEC_FLAG_READ_PERMISSION ) { *ca++ = 'r'; } if( flags & ORL_SEC_FLAG_WRITE_PERMISSION ) { *ca++ = 'w'; } if( flags & ORL_SEC_FLAG_EXECUTE_PERMISSION ) { *ca++ = 'x'; } if( flags & ORL_SEC_FLAG_SHARED ) { *ca++ = 's'; } *ca++ = '0' + alignment; *ca = '\0'; if( !( DFormat & DFF_ASM ) ){ BufferConcat("\t\t\t\t"); } BufferStore(".new_section %s, \"%s\"", sec->name, attributes ); } else { if( !(flags & ORL_SEC_FLAG_REMOVE ) ) { *ca++ = 'a'; } if( flags & ORL_SEC_FLAG_EXEC ) { *ca++ = 'x'; } if( flags & ORL_SEC_FLAG_WRITE_PERMISSION ) { *ca++ = 'w'; } *ca++ = '\0'; if( !( DFormat & DFF_ASM ) ) { BufferConcat("\t\t\t\t"); } BufferStore(".section %s, \"%s\"", sec->name, attributes ); BufferConcatNL(); if( !( DFormat & DFF_ASM ) ) { BufferConcat("\t\t\t\t"); } BufferStore(".align %d", (int)alignment ); } BufferConcatNL(); BufferPrint(); }