📄 omfmunge.c
字号:
flags |= ORL_SEC_FLAG_READ_PERMISSION;
slen = OmfGetLName( ofh->lnames, name, lname );
lname[slen] = '\0';
strNUpper( lname, slen );
if( ( slen > 3 ) &&
( !strcmp( "CODE", &lname[slen - 4] ) ||
!strcmp( "TEXT", &lname[slen - 4] ) ) ) {
flags |= ORL_SEC_FLAG_EXEC | ORL_SEC_FLAG_EXECUTE_PERMISSION;
}
}
} else {
flags |= ORL_SEC_FLAG_READ_PERMISSION;
}
if( use32 ) {
flags |= ORL_SEC_FLAG_USE_32;
}
return( flags );
}
orl_return OmfAddLIData( omf_file_handle ofh, int is32,
omf_idx seg, orl_sec_offset offset,
omf_bytes buffer, long len, int comdat )
{
omf_sec_handle sh;
orl_return err;
orl_sec_offset size;
orl_sec_offset tmpsize;
omf_bytes tmp;
int tmplen;
assert( ofh );
assert( buffer );
assert( seg );
err = finishPrevWork( ofh );
if( err != ORL_OKAY ) return( err );
if( comdat ) {
sh = findComDat( ofh, seg );
} else {
sh = findSegment( ofh, seg );
}
if( !sh ) return( ORL_ERROR );
if( len < 0 ) return( ORL_ERROR );
tmp = buffer;
tmplen = len;
size = 0;
while( tmplen > 0 ) {
if( ofh->status & OMF_STATUS_EASY_OMF ) {
tmpsize = calcLIDataLength( 0, &tmp, &tmplen );
} else {
tmpsize = calcLIDataLength( is32, &tmp, &tmplen );
}
if( tmpsize == 0 ) return( ORL_ERROR );
size += tmpsize;
}
err = checkSegmentLength( sh, offset + size );
if( err != ORL_OKAY ) return( err );
/* we put off expanding the lidata until all the fixups are in
*/
if( !ofh->lidata ) {
ofh->lidata = _ClientAlloc( ofh, sizeof( omf_tmp_lidata_struct ) );
if( !ofh->lidata ) return( ORL_OUT_OF_MEMORY );
}
memset( ofh->lidata, 0, sizeof( omf_tmp_lidata_struct ) );
ofh->lidata->size = len;
ofh->lidata->is32 = is32;
sh->assoc.seg.cur_offset = offset;
memcpy( sh->contents + offset, buffer, len );
ofh->status |= OMF_STATUS_ADD_LIDATA;
ofh->work_sec = sh;
return( err );
}
orl_return OmfAddLEData( omf_file_handle ofh, int is32,
omf_idx seg, orl_sec_offset offset,
omf_bytes buffer, long len, int comdat )
{
omf_sec_handle sh;
orl_return err;
is32 = is32;
assert( ofh );
assert( buffer );
assert( seg );
err = finishPrevWork( ofh );
if( err != ORL_OKAY ) return( err );
if( comdat ) {
sh = findComDat( ofh, seg );
} else {
sh = findSegment( ofh, seg );
}
if( !sh ) return( ORL_ERROR );
if( len < 0 ) return( ORL_ERROR );
err = checkSegmentLength( sh, offset + len );
if( err != ORL_OKAY ) return( err );
sh->assoc.seg.cur_offset = offset;
memcpy( sh->contents + offset, buffer, len );
ofh->work_sec = sh;
return( err );
}
orl_return OmfAddLName( omf_file_handle ofh, omf_bytes buffer,
unsigned int len, omf_rectyp typ )
{
assert( ofh );
assert( buffer );
typ = typ;
if( !ofh->lnames ) {
ofh->lnames = newStringTable( ofh, OMF_SEC_LNAME_INDEX );
if( !ofh->lnames ) return( ORL_OUT_OF_MEMORY );
ofh->lnames->flags = ORL_SEC_FLAG_REMOVE;
}
return( addString( ofh->lnames, buffer, len ) );
}
orl_return OmfAddFixupp( omf_file_handle ofh, int is32, int mode,
int location, orl_sec_offset offset,
int fmethod, omf_idx fidx, int tmethod,
omf_idx tidx, orl_sec_offset disp )
{
omf_tmp_fixup tfr;
omf_reloc_handle orel;
omf_sec_handle sh;
omf_grp_handle gr;
assert( ofh );
if( ofh->status & OMF_STATUS_ADD_LIDATA ) {
assert( ofh->work_sec );
assert( ofh->lidata );
tfr = _ClientAlloc( ofh, sizeof( omf_tmp_fixup_struct ) );
if( !tfr ) return( ORL_OUT_OF_MEMORY );
memset( tfr, 0, sizeof( omf_tmp_fixup_struct ) );
if( fmethod == FRAME_LOC ) {
fmethod = FRAME_SEG;
fidx = ofh->work_sec->assoc.seg.seg_id;
}
tfr->is32 = is32;
tfr->mode = mode;
tfr->location = location;
tfr->offset = offset;
tfr->fmethod = fmethod;
tfr->fidx = fidx;
tfr->tmethod = tmethod;
tfr->tidx = tidx;
tfr->disp = disp;
if( ofh->lidata->last_fixup ) {
ofh->lidata->last_fixup->next = tfr;
} else {
ofh->lidata->first_fixup = tfr;
}
ofh->lidata->last_fixup = tfr;
return( ORL_OKAY );
}
orel = _ClientAlloc( ofh, sizeof( omf_reloc_handle_struct ) );
if( !orel ) return( ORL_OUT_OF_MEMORY );
memset( orel, 0, sizeof( omf_reloc_handle_struct ) );
switch( location ) {
case( LOC_OFFSET_LO ): /* relocate lo byte of offset */
/* should be 8 rather then 16, fix later
*/
if( mode ) {
orel->type = ORL_RELOC_TYPE_WORD_8;
} else {
orel->type = ORL_RELOC_TYPE_REL_8;
}
break;
case( LOC_OFFSET ): /* relocate offset */
if( mode ) {
orel->type = ORL_RELOC_TYPE_WORD_16;
} else {
orel->type = ORL_RELOC_TYPE_REL_16;
}
break;
case( LOC_BASE ): /* relocate segment */
orel->type = ORL_RELOC_TYPE_SEGMENT;
break;
case( LOC_BASE_OFFSET ): /* relocate segment and offset */
if( mode ) {
orel->type = ORL_RELOC_TYPE_WORD_16_SEG;
} else {
orel->type = ORL_RELOC_TYPE_REL_16_SEG;
}
break;
case( LOC_OFFSET_HI ): /* relocate hi byte of offset */
if( mode ) {
orel->type = ORL_RELOC_TYPE_WORD_HI_8;
} else {
orel->type = ORL_RELOC_TYPE_REL_HI_8;
}
break;
case( LOC_OFFSET_32 ): /* relocate 32-bit offset */
case( LOC_MS_OFFSET_32 ): /* MS 32-bit offset */
case( LOC_MS_LINK_OFFSET_32 ): /* like OFFSET_32, ldr resolved */
if( mode ) {
orel->type = ORL_RELOC_TYPE_WORD_32;
} else {
orel->type = ORL_RELOC_TYPE_REL_32;
}
break;
case( LOC_BASE_OFFSET_32 ): /* relocate seg and 32bit offset*/
case( LOC_MS_BASE_OFFSET_32 ): /* MS 48-bit pointer */
if( mode ) {
orel->type = ORL_RELOC_TYPE_WORD_32_SEG;
} else {
orel->type = ORL_RELOC_TYPE_REL_32_SEG;
}
break;
default:
return( ORL_ERROR );
}
/* no section for fixups to refer to
*/
if( !ofh->work_sec ) return( ORL_ERROR );
orel->offset = offset + ofh->work_sec->assoc.seg.cur_offset;
orel->section = (orl_sec_handle)(ofh->work_sec);
orel->addend = disp;
if( fmethod == FRAME_LOC ) {
fmethod = FRAME_SEG;
fidx = ofh->work_sec->assoc.seg.seg_id;
}
switch( tmethod ) {
case( TARGET_SEGWD ): /* segment index with displacement */
case( TARGET_SEG ): /* segment index, no displacement */
sh = findSegment( ofh, tidx );
if( !sh ) return( ORL_ERROR );
orel->symbol = (orl_symbol_handle)(sh->assoc.seg.sym);
break;
case( TARGET_GRPWD ): /* group index with displacement */
case( TARGET_GRP ): /* group index, no displacement */
gr = findGroup( ofh, tidx );
if( !gr ) return( ORL_ERROR );
orel->symbol = (orl_symbol_handle)(gr->sym);
break;
case( TARGET_EXTWD ): /* external index with displacement */
case( TARGET_EXT ): /* external index, no displacement */
orel->symbol = (orl_symbol_handle)(findExtDefSym( ofh, tidx ));
if( !orel->symbol ) return( ORL_ERROR );
break;
case( TARGET_ABSWD ): /* abs frame num with displacement */
case( TARGET_ABS ): /* abs frame num, no displacement */
break;
default:
return( ORL_ERROR );
}
switch( fmethod ) {
case( FRAME_SEG ): /* segment index */
sh = findSegment( ofh, fidx );
if( !sh ) return( ORL_ERROR );
orel->frame = (orl_symbol_handle)(sh->assoc.seg.sym);
break;
case( FRAME_GRP ): /* group index */
gr = findGroup( ofh, fidx );
if( !gr ) return( ORL_ERROR );
orel->frame = (orl_symbol_handle)(gr->sym);
break;
case( FRAME_EXT ): /* external index */
orel->frame = (orl_symbol_handle)(findExtDefSym( ofh, fidx ));
if( !orel->frame ) return( ORL_ERROR );
break;
case( FRAME_ABS ): /* absolute frame number */
/* fix this up to do somehting later */
orel->frame = NULL;
break;
case( FRAME_TARG ): /* frame same as target */
orel->frame = orel->symbol;
break;
case( FRAME_LOC ): /* frame containing location */
assert( 0 );
}
return( addReloc( ofh, orel ) );
}
orl_return OmfAddExtDef( omf_file_handle ofh, omf_bytes buffer,
unsigned int len, omf_rectyp typ )
{
omf_symbol_handle sym;
orl_return err;
orl_symbol_type styp;
assert( ofh );
assert( buffer );
typ = typ;
if( !ofh->extdefs ) {
ofh->extdefs = newStringTable( ofh, OMF_SEC_IMPORT_INDEX );
if( !ofh->extdefs ) return( ORL_OUT_OF_MEMORY );
ofh->extdefs->flags = ORL_SEC_FLAG_REMOVE;
}
styp = ORL_SYM_TYPE_OBJECT;
if( ( typ == CMD_COMDEF ) || ( typ == CMD_LCOMDEF ) ) {
styp |= ORL_SYM_TYPE_COMMON;
} else {
styp |= ORL_SYM_TYPE_UNDEFINED;
}
sym = newSymbol( ofh, styp, buffer, len );
if( !sym ) return( ORL_OUT_OF_MEMORY );
sym->idx = ofh->extdefs->assoc.string.num + 1;
sym->rec_typ = typ;
switch( typ ) {
case( CMD_COMDEF ):
case( CMD_LCOMDEF ):
sym->flags |= OMF_SYM_FLAGS_COMDEF;
sym->binding = ORL_SYM_BINDING_GLOBAL;
if( typ == CMD_COMDEF ) break;
case( CMD_LEXTDEF ):
case( CMD_LEXTDEF32 ):
sym->flags |= OMF_SYM_FLAGS_LOCAL;
sym->binding = ORL_SYM_BINDING_LOCAL;
}
err = addToSymbolTable( ofh, sym );
if( err != ORL_OKAY ) return( err );
return( addString( ofh->extdefs, buffer, len ) );
}
orl_return OmfAddComDat( omf_file_handle ofh, int is32, int flags,
int attr, int align,
orl_sec_offset offset, omf_idx seg,
omf_idx group, omf_frame frame,
omf_idx name, omf_bytes buffer, long len,
omf_rectyp typ )
{
orl_return err;
omf_sec_handle sh;
omf_symbol_handle sym;
char lname[257];
int slen;
orl_symbol_type styp;
long size;
typ = typ;
assert( ofh );
assert( buffer );
err = finishPrevWork( ofh );
if( err != ORL_OKAY ) return( err );
if( align == -1 ) {
if( !seg ) return( ORL_ERROR );
sh = findSegment( ofh, seg );
if( !sh ) return( ORL_ERROR );
align = sh->assoc.seg.alignment;
}
if( flags & COMDAT_CONTINUE ) {
sh = findComDatByName( ofh, name );
if( !sh ) return( ORL_ERROR );
} else {
/* Create new Comdat
*/
sh = newComDatSection( ofh );
if( !sh ) return( ORL_OUT_OF_MEMORY );
sh->assoc.seg.name = name;
sh->assoc.seg.comdat.frame = frame;
sh->assoc.seg.alignment = align;
if( is32 ) {
sh->assoc.seg.seg_flags |= OMF_SEG_IS_32;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -