target_offset_t SegmentAlignment( // SEGMENT: ALIGNMENT FOR SYMBOL SYMBOL sym ) // - symbol to align { target_offset_t align; TYPE type; TYPE align_type; if( CompFlags.dont_align_segs ) { return( TARGET_CHAR ); } #if _CPU == _AXP if( PackAmount != TARGET_CHAR ) { #else if( OptSize <= 50 || PackAmount != TARGET_CHAR ) { #endif type = sym->sym_type; align_type = AlignmentType( type ); align = segmentTypeSize( align_type ); if( align == TARGET_CHAR ) { // no alignment; let PackAlignment know the real size align = segmentTypeSize( type ); } align = PackAlignment( TARGET_MAX_PACKING, align ); } else { align = TARGET_CHAR; } return( align ); } target_offset_t SegmentAdjust( // SEGMENT: ADJUST OFFSET TO ALIGN fe_seg_id segid, // - segment identifier target_size_t offset, // - current offset target_offset_t align ) // - required aligment { target_size_t calc_offset; target_offset_t adjust; switch( segid ) { case SEG_INIT_BEG: case SEG_INIT_REF: case SEG_INIT_END: case SEG_FINI_BEG: case SEG_FINI_REF: case SEG_FINI_END: /* no padding in these segments */ return( 0 ); } calc_offset = offset; calc_offset += align - 1; calc_offset &= ~(((target_size_t) align ) - 1 ); adjust = calc_offset - offset; _CHECK_ADJUST( adjust, calc_offset, offset ); return( adjust ); }
static bool same_segment( // DETERMINE IF SAME SEGMENT void * _curr, // - current segment const void * _lk ) // - segment lookup structure { PC_SEGMENT *curr = _curr; const struct seg_look* lk = _lk; target_offset_t align_adjust; target_size_t new_offset; if( lk->use_seg_id && lk->seg_id != SEG_NULL && curr->seg_id != lk->seg_id ) { return( FALSE ); } if( lk->use_attrs && curr->attrs != lk->attrs ) { return( FALSE ); } if( lk->use_align && curr->align != lk->align ) { return( FALSE ); } if( lk->use_sym_size_align ) { align_adjust = SegmentAdjust( curr->seg_id, curr->offset, lk->sym_align ); new_offset = curr->offset + align_adjust + lk->sym_size; if( _CHECK_ADJUST( new_offset, curr->offset ) ) { new_offset = 0; } if( new_offset == 0 ) { return( FALSE ); } } if( lk->use_name ) { if( strcmp( curr->name, lk->seg_name ) != 0 ) { return( FALSE ); } if( curr->class_name != NULL ) { if( lk->class_name == NULL ) { return( FALSE ); } if( strcmp( curr->class_name, lk->class_name ) != 0 ) { return( FALSE ); } } else { if( lk->class_name != NULL ) { return( FALSE ); } } } if( lk->use_only_strings && !curr->only_strings ) { return( FALSE ); } return( TRUE ); }
fe_seg_id SegmentAddSym( // SEGMENT: ADD SYMBOL TO SPECIFIED SEGMENT SYMBOL sym, // - sym to add fe_seg_id id, // - id of segment to use target_size_t size, // - size of sym target_offset_t align ) // - alignment for sym { PC_SEGMENT *curr; // - new segment target_size_t aligned_offset; target_size_t calc_offset; target_size_t total_size; if( id == SEG_DATA || ( id == SEG_BSS && flags.use_def_seg ) ) { curr = data_def_seg.pcseg; id = curr->seg_id; } else if( id == SEG_CODE ) { curr = code_def_seg.pcseg; id = curr->seg_id; } else { curr = segIdLookup( id ); } if( curr == NULL ) { CFatal( "segment: cannot find default segment" ); } else { accumAlignment( curr, align ); if( ( ! SymIsInitialized( sym ) ) && SymIsExtern( sym ) ) { id = curr->seg_id; _markUsed( curr, TRUE ); curr->has_data = TRUE; data_def_seg.ds_used = TRUE; } else { aligned_offset = SegmentAdjust( curr->seg_id, curr->offset, align ); calc_offset = curr->offset + aligned_offset + size; _CHECK_ADJUST( calc_offset, calc_offset, curr->offset ); if( calc_offset == 0 ) { if( size != 0 ) { CErr( ERR_MAX_SEGMENT_EXCEEDED, curr->name, sym ); } id = SEG_NULL; } else if( curr->dgroup ) { total_size = dgroup_size + size + aligned_offset; _CHECK_ADJUST( calc_offset, total_size, dgroup_size ); if( calc_offset == 0 ) { if( size != 0 ) { CErr( ERR_MAX_DGROUP_EXCEEDED, sym, curr->name ); } id = SEG_NULL; } else { dgroup_size += size + aligned_offset; curr->offset = calc_offset; _markUsed( curr, TRUE ); curr->has_data = TRUE; id = curr->seg_id; data_def_seg.ds_used = TRUE; } } else { curr->offset = calc_offset; _markUsed( curr, TRUE ); curr->has_data = TRUE; id = curr->seg_id; data_def_seg.ds_used = TRUE; } } } return id; }