📄 omfmunge.c
字号:
}
sh->flags |= ORL_SEC_FLAG_COMDAT | ORL_SEC_FLAG_READ_PERMISSION |
ORL_SEC_FLAG_INITIALIZED_DATA;
sh->assoc.seg.combine = ORL_SEC_COMBINE_COMDAT;
switch( attr & COMDAT_ALLOC_MASK ) {
case( COMDAT_EXPLICIT ): /* in given segment */
sh->assoc.seg.comdat.assoc_seg = findSegment( ofh, seg );
if( !sh->assoc.seg.comdat.assoc_seg ) return( ORL_ERROR );
sh->flags |= sh->assoc.seg.comdat.assoc_seg->flags;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_EXPLIC;
if( group ) {
sh->assoc.seg.comdat.group = findGroup( ofh, group );
}
break;
case( COMDAT_FAR_CODE ): /* allocate CODE use16 segment */
sh->flags |= ORL_SEC_FLAG_EXEC | ORL_SEC_FLAG_EXECUTE_PERMISSION;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_CODE16;
break;
case( COMDAT_CODE32 ): /* allocate CODE use32 segment */
sh->flags |= ORL_SEC_FLAG_EXEC | ORL_SEC_FLAG_EXECUTE_PERMISSION;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_CODE32;
break;
case( COMDAT_FAR_DATA ): /* allocate DATA use16 segment */
sh->flags |= ORL_SEC_FLAG_WRITE_PERMISSION;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_DATA16;
break;
case( COMDAT_DATA32 ): /* allocate DATA use32 segment */
sh->flags |= ORL_SEC_FLAG_WRITE_PERMISSION;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_DATA32;
break;
}
/* Create symbol for section using its name, when looking up we will
* need to match the indexes for proper matching
*/
styp = ORL_SYM_TYPE_SECTION | ORL_SYM_TYPE_COMMON;
switch( attr & COMDAT_MATCH_MASK ) {
case( COMDAT_MATCH_NONE ): /* don't match anyone */
styp |= ORL_SYM_CDAT_NODUPLICATES;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_NONE;
break;
case( COMDAT_MATCH_ANY ): /* pick any instance */
styp |= ORL_SYM_CDAT_ANY;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_ANY;
break;
case( COMDAT_MATCH_SAME ): /* must be same size */
styp |= ORL_SYM_CDAT_SAME_SIZE;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_SAME;
break;
case( COMDAT_MATCH_EXACT ): /* must be exact match */
styp |= ORL_SYM_CDAT_EXACT;
sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_EXACT;
break;
}
slen = OmfGetLName( ofh->lnames, name, lname );
if( slen < 0 ) return( ORL_ERROR );
sym = newSymbol( ofh, styp, lname, slen );
sym->seg = name;
sym->idx = sh->assoc.seg.seg_id;
sh->assoc.seg.sym = sym;
sym->section = sh;
if( flags & COMDAT_LOCAL ) {
sym->binding = ORL_SYM_BINDING_LOCAL;
sym->flags |= OMF_SYM_FLAGS_LOCAL;
} else {
sym->binding = ORL_SYM_BINDING_GLOBAL;
}
err = addToSymbolTable( ofh, sym );
if( err != ORL_OKAY ) return( err );
}
size = offset + len;
if( size > sh->size ) {
sh->size = size;
}
if( flags & COMDAT_ITERATED ) {
err = OmfAddLIData( ofh, is32, sh->assoc.seg.seg_id, offset, buffer,
len, 1 );
} else {
err = OmfAddLEData( ofh, is32, sh->assoc.seg.seg_id, offset, buffer,
len, 1 );
}
return( err );
}
extern orl_return OmfAddLineNum( omf_file_handle ofh, omf_idx seg,
omf_idx name, unsigned_16 line,
unsigned_32 offset )
{
omf_sec_handle sh;
assert( ofh );
sh = OmfFindSegOrComdat( ofh, seg, name );
if( !sh ) return( ORL_ERROR );
sh->assoc.seg.lines = checkArraySize( ofh, sh->assoc.seg.lines,
sh->assoc.seg.num_lines, STD_INC,
sizeof( orl_linnum ) );
if( !sh->assoc.seg.lines ) return( ORL_OUT_OF_MEMORY );
sh->assoc.seg.lines[ sh->assoc.seg.num_lines ].linnum = line;
sh->assoc.seg.lines[ sh->assoc.seg.num_lines ].off = offset;
sh->assoc.seg.num_lines++;
return( ORL_OKAY );
}
orl_return OmfAddSegDef( omf_file_handle ofh, int is32,
orl_sec_alignment align, int combine,
int use32, int max, orl_sec_frame frame,
orl_sec_size size, omf_idx name,
omf_idx class )
{
omf_sec_handle sh;
omf_symbol_handle sym;
char lname[257];
int len;
assert( ofh );
sh = newSegSection( ofh, ORL_SEC_TYPE_PROG_BITS );
if( !sh ) return( ORL_OUT_OF_MEMORY );
sh->assoc.seg.name = name;
sh->assoc.seg.class = class;
sh->assoc.seg.alignment = align;
sh->assoc.seg.combine = getCombine( combine );
sh->assoc.seg.frame = frame;
if( is32 ) {
sh->assoc.seg.seg_flags |= OMF_SEG_IS_32;
}
if( frame > ORL_SEC_NO_ABS_FRAME ) {
sh->assoc.seg.seg_flags |= OMF_SEG_IS_ABS;
}
if( max ) {
sh->assoc.seg.seg_flags |= OMF_SEG_IS_BIG;
if( is32 ) {
sh->size = 0xffffffff;
} else {
sh->size = 0x10000;
}
} else {
sh->size = size;
}
sh->flags |= getSegSecFlags( ofh, name, class, align, combine, use32 );
if( sh->flags & ORL_SEC_FLAG_UNINITIALIZED_DATA ) {
sh->type = ORL_SEC_TYPE_NO_BITS;
}
/* Create symbol for section using its name, when looking up we will
* need to match the indexes for proper matching
*/
len = OmfGetLName( ofh->lnames, name, lname );
if( len < 0 ) return( ORL_ERROR );
sym = newSymbol( ofh, ORL_SYM_TYPE_SECTION, lname, len );
sym->seg = name;
sym->idx = sh->assoc.seg.seg_id;
sh->assoc.seg.sym = sym;
sym->section = sh;
return( addToSymbolTable( ofh, sym ) );
}
orl_return OmfAddPubDef( omf_file_handle ofh, int is32,
omf_idx group, omf_idx seg,
omf_frame frame, char *name, int len,
orl_sec_offset offset, omf_rectyp typ )
{
omf_symbol_handle sym;
orl_symbol_type styp;
is32 = is32;
assert( ofh );
assert( name );
if( !seg && group ) {
/* we currently don't handle this, presumably it does not occur.
*/
return( ORL_ERROR );
} else if( !seg && !group ) {
styp = ORL_SYM_TYPE_ABSOLUTE;
} else {
styp = ORL_SYM_TYPE_DEFINED;
}
styp |= ORL_SYM_TYPE_OBJECT;
sym = newSymbol( ofh, styp, name, len );
if( !sym ) return( ORL_OUT_OF_MEMORY );
sym->seg = seg;
sym->frame = frame;
sym->offset = offset;
sym->rec_typ = typ;
if( ( typ == CMD_LPUBDEF ) || ( typ == CMD_LPUBDEF32 ) ) {
sym->flags |= OMF_SYM_FLAGS_LOCAL;
sym->binding = ORL_SYM_BINDING_LOCAL;
} else {
sym->binding = ORL_SYM_BINDING_GLOBAL;
}
if( styp & ORL_SYM_TYPE_DEFINED ) {
sym->section = findSegment( ofh, seg );
}
return( addToSymbolTable( ofh, sym ) );
}
orl_return OmfAddGrpDef( omf_file_handle ofh, omf_idx name,
omf_idx *segs, int size )
{
omf_symbol_handle sym;
omf_sec_handle sh;
char lname[257];
int len;
omf_grp_handle gr;
assert( ofh );
assert( segs );
if( !name ) return( ORL_ERROR );
gr = newGroup( ofh );
if( !gr ) return( ORL_OUT_OF_MEMORY );
gr->segs = segs;
gr->name = name;
gr->size = size;
while( size ) {
size--;
sh = findSegment( ofh, segs[size] );
if( !sh ) return( ORL_ERROR );
sh->flags |= ORL_SEC_FLAG_GROUPED;
sh->assoc.seg.group = gr;
}
len = OmfGetLName( ofh->lnames, name, lname );
if( len < 0 ) return( ORL_ERROR );
sym = newSymbol( ofh, ORL_SYM_TYPE_GROUP, lname, len );
if( !sym ) return( ORL_OUT_OF_MEMORY );
sym->flags |= OMF_SYM_FLAGS_GRPDEF;
sym->idx = gr->id;
gr->sym = sym;
return( addToSymbolTable( ofh, sym ) );
}
orl_return OmfModEnd( omf_file_handle ofh )
{
orl_return err;
omf_symbol_handle sym;
assert( ofh );
err = finishPrevWork( ofh );
if( err != ORL_OKAY ) return( err );
sym = newSymbol( ofh, ORL_SYM_TYPE_FILE, ofh->modname, ofh->modnamelen );
if( !sym ) return( ORL_OUT_OF_MEMORY );
return( addToSymbolTable( ofh, sym ) );
}
extern orl_return OmfAddComment( omf_file_handle ofh, uint_8 class,
uint_8 flags, omf_bytes buff, long len )
{
omf_sec_handle sh;
omf_comment_struct *comment;
assert( ofh );
assert( buff );
sh = ofh->comments;
if( !sh ) {
sh = newSection( ofh, OMF_SEC_COMMENT_INDEX, ORL_SEC_TYPE_NOTE );
if( !sh ) return( ORL_OUT_OF_MEMORY );
sh->flags |= ORL_SEC_FLAG_REMOVE;
ofh->comments = sh;
}
sh->assoc.comment.comments = checkArraySize(ofh, sh->assoc.comment.comments,
sh->assoc.comment.num, STD_INC,
sizeof(omf_comment_struct *) );
if( !sh->assoc.comment.comments ) return( ORL_OUT_OF_MEMORY );
comment = _ClientAlloc( ofh, sizeof( omf_comment_struct ) + len );
if( !comment ) return( ORL_OUT_OF_MEMORY );
memset( comment, 0, sizeof( omf_comment_struct ) + len );
comment->class = class;
comment->flags = flags;
comment->len = len;
memcpy( comment->data, buff, len );
comment->data[len] = 0;
sh->assoc.comment.comments[sh->assoc.comment.num] = comment;
sh->assoc.comment.num++;
return( ORL_OKAY );
}
int OmfGetLName( omf_sec_handle lnames, omf_idx idx, char *name )
{
omf_string_struct *tmp;
assert( lnames );
assert( name );
assert( lnames->type == ORL_SEC_TYPE_STR_TABLE );
*name = '\0';
if( !idx ) {
return( 0 );
}
idx--;
tmp = getIdx2String( lnames, idx );
if( !tmp ) {
return( -1 );
}
memcpy( name, tmp->string, tmp->len );
name[tmp->len] = '\0';
return( tmp->len );
}
char *OmfGetPtrToLName( omf_file_handle ofh, omf_idx idx )
{
omf_string_struct *tmp;
assert( ofh );
if( !ofh->lnames || ( idx < 1 ) ) return( NULL );
idx--;
tmp = getIdx2String( ofh->lnames, idx );
if( !tmp ) return( NULL );
return( tmp->string );
}
omf_sec_handle OmfFindSegOrComdat( omf_file_handle ofh, omf_idx seg,
omf_idx comdat_lname )
{
omf_quantity x;
assert( ofh );
if( seg ) {
return( findSegment( ofh, seg ) );
} else {
assert( comdat_lname );
for( x = 0; x < ofh->num_comdats; x++ ) {
if( nameCmp(ofh, ofh->comdats[x]->assoc.seg.name, comdat_lname) == 0 ) {
return( ofh->comdats[x] );
}
}
}
return( NULL );
}
orl_return OmfExportSegmentContents( omf_sec_handle sh )
{
assert( sh );
if( sh->size > 0 ) {
return( checkSegmentLength( sh, sh->size ) );
}
return( ORL_OKAY );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -