📄 omfload.c
字号:
use32 = 1;
if( len >= 1 ) {
datum = buffer[0];
if( !(datum & EASY_USE32_FIELD ) ) {
use32 = 0;
}
}
}
if( use32 && !( ofh->status & OMF_STATUS_ARCH_SET ) ) {
ofh->machine_type = ORL_MACHINE_TYPE_I386;
_SetWordSize( ofh->flags, ORL_FILE_FLAG_32BIT_MACHINE );
ofh->status |= OMF_STATUS_ARCH_SET;
}
return( OmfAddSegDef( ofh, is32, align, combine, use32, max, frame, size,
name, class ) );
}
static orl_return doGRPDEF( omf_file_handle ofh )
{
orl_return err;
omf_bytes buffer;
long len;
omf_idx name;
omf_idx *segs;
orl_sec_size size;
assert( ofh );
err = loadRecord( ofh );
if( err != ORL_OKAY ) return( err );
len = ofh->parselen;
buffer = ofh->parsebuf;
if( ( len < 1 ) || !( len & 1 ) ) return( ORL_ERROR );
name = loadIndex( &buffer, &len );
/* assume maximum possible group size of len / 2, max number of
* segs is about 32768.
*/
if( len > 65536 ) return( ORL_ERROR );
size = ( ( len / 2 ) + 1 ) * sizeof( omf_idx );
segs = _ClientAlloc( ofh, size );
if( !segs ) return( ORL_OUT_OF_MEMORY );
memset( segs, 0, size );
size = 0;
while( len ) {
if( buffer[0] != 0xff ) return( ORL_ERROR );
buffer++;
len--;
segs[size] = loadIndex( &buffer, &len );
size++;
}
return( OmfAddGrpDef( ofh, name, segs, size ) );
}
static orl_return doFIXUPP( omf_file_handle ofh, omf_rectyp typ )
{
orl_return err;
omf_bytes buffer;
long len;
uint_8 datum;
int is32;
int wordsize;
assert( ofh );
err = loadRecord( ofh );
if( err != ORL_OKAY ) return( err );
is32 = check32Bit( ofh, typ );
wordsize = OmfGetWordSize( is32 );
len = ofh->parselen;
buffer = ofh->parsebuf;
if( len < 0 ) return( ORL_ERROR );
while( len ) {
/* determine if it is a thread or fixupp subrecord
* and act upon it
*/
datum = buffer[0];
if( datum & 0x80 ) {
err = processExplicitFixup( ofh, is32, &buffer, &len );
} else {
err = processThreadFixup( ofh, &buffer, &len );
}
if( err != ORL_OKAY ) break;
}
return( err );
}
static orl_return doLEDATA( omf_file_handle ofh, omf_rectyp typ )
{
orl_return err;
int is32;
omf_bytes buffer;
long len;
int wordsize;
omf_idx seg;
orl_sec_offset offset;
assert( ofh );
is32 = check32Bit( ofh, typ );
wordsize = OmfGetWordSize( is32 );
err = loadRecord( ofh );
if( err != ORL_OKAY ) return( err );
len = ofh->parselen;
buffer = ofh->parsebuf;
if( len < ( wordsize + 1 ) ) return( ORL_ERROR );
seg = loadIndex( &buffer, &len );
if( !seg ) return( ORL_ERROR );
offset = getUWord( buffer, wordsize );
buffer += wordsize;
len -= wordsize;
if( len < 0 ) return( ORL_ERROR );
return( OmfAddLEData( ofh, is32, seg, offset, buffer, len, 0 ) );
}
static orl_return doLIDATA( omf_file_handle ofh, omf_rectyp typ )
{
orl_return err;
int is32;
omf_bytes buffer;
long len;
int wordsize;
omf_idx seg;
orl_sec_offset offset;
assert( ofh );
is32 = check32Bit( ofh, typ );
wordsize = OmfGetWordSize( is32 );
err = loadRecord( ofh );
if( err != ORL_OKAY ) return( err );
len = ofh->parselen;
buffer = ofh->parsebuf;
if( len < ( wordsize + 1 ) ) return( ORL_ERROR );
seg = loadIndex( &buffer, &len );
if( !seg ) return( ORL_ERROR );
offset = getUWord( buffer, wordsize );
buffer += wordsize;
len -= wordsize;
if( len < 0 ) return( ORL_ERROR );
/* LIData must be processed after the fixups have been read in, in order
* to clone them appropriately, evil but necessary, we have no choice in
* the matter, the conversion will create an LEData which will then be
* added to the section.
*/
return( OmfAddLIData( ofh, is32, seg, offset, buffer, len, 0 ) );
}
static orl_return doCOMDAT( omf_file_handle ofh, omf_rectyp typ )
{
orl_return err;
int is32;
omf_bytes buffer;
long len;
int wordsize;
omf_idx seg = 0;
omf_idx group = 0;
omf_frame frame = 0;
omf_idx name;
uint_8 attr;
int align;
uint_8 flags;
orl_sec_offset offset;
assert( ofh );
is32 = check32Bit( ofh, typ );
wordsize = OmfGetWordSize( is32 );
err = loadRecord( ofh );
if( err != ORL_OKAY ) return( err );
len = ofh->parselen;
buffer = ofh->parsebuf;
if( len < ( wordsize + 3 ) ) return( ORL_ERROR );
flags = buffer[0];
attr = buffer[1];
align = buffer[2];
if( align == COMDAT_ALIGN_SEG ) {
align = -1;
} else {
align = getAlignment( align );
}
buffer += 3;
len -= 3;
offset = getUWord( buffer, wordsize );
buffer += wordsize;
len -= wordsize;
loadIndex( &buffer, &len );
if( ( attr & COMDAT_ALLOC_MASK ) == COMDAT_EXPLICIT ) {
group = loadIndex( &buffer, &len );
seg = loadIndex( &buffer, &len );
if( !seg && !group ) {
frame = getUWord( buffer, 2 );
buffer += 2;
len -= 2;
}
}
name = loadIndex( &buffer, &len );
return( OmfAddComDat( ofh, is32, flags, attr, align, offset, seg, group,
frame, name, buffer, len, typ ) );
}
static orl_return procRecord( omf_file_handle ofh, omf_rectyp typ )
{
assert( ofh );
switch( typ ) {
case( CMD_COMENT ): /* comment record */
return( doCOMENT( ofh ) );
case( CMD_MODEND ): /* end of module record */
case( CMD_MODEND32 ): /* 32-bit end of module record */
return( doMODEND( ofh, typ ) );
case( CMD_EXTDEF ): /* import names record */
case( CMD_LEXTDEF ): /* local import names record */
case( CMD_LEXTDEF32 ): /* 32-bit local import names record */
return( doEXTDEF( ofh, typ ) );
case( CMD_CEXTDF ): /* external reference to a COMDAT */
return( doCEXTDEF( ofh, typ ) );
case( CMD_PUBDEF ): /* export names record */
case( CMD_PUBDEF32 ): /* 32-bit export names record */
case( CMD_LPUBDEF ): /* static export names record */
case( CMD_LPUBDEF32 ): /* static export names record */
return( doPUBDEF( ofh, typ ) );
case( CMD_LNAMES ): /* list of names record */
case( CMD_LLNAME ): /* a "local" lnames */
return( doLNAMES( ofh, typ ) );
case( CMD_SEGDEF ): /* segment definition record */
case( CMD_SEGDEF32 ): /* 32-bit segment definition */
return( doSEGDEF( ofh, typ ) );
case( CMD_GRPDEF ): /* group definition record */
return( doGRPDEF( ofh ) );
case( CMD_FIXUPP ): /* relocation record */
case( CMD_FIXUPP32 ): /* 32-bit relocation record */
return( doFIXUPP( ofh, typ ) );
case( CMD_LEDATA ): /* object record */
case( CMD_LEDATA32 ): /* 32-bit object record */
return( doLEDATA( ofh, typ ) );
case( CMD_LIDATA ): /* repeated data record */
case( CMD_LIDATA32 ): /* 32-bit repeated data record */
return( doLIDATA( ofh, typ ) );
case( CMD_COMDAT ): /* initialized communal data record */
case( CMD_COMDAT32 ): /* initialized 32-bit communal data rec */
return( doCOMDAT( ofh, typ ) );
case( CMD_COMDEF ): /* communal definition */
case( CMD_LCOMDEF ): /* local comdev */
return( doCOMDEF( ofh, typ ) );
case( CMD_LINNUM ): /* line number record */
case( CMD_LINNUM32 ): /* 32-bit line number record. */
case( CMD_LINSYM ): /* LINNUM for a COMDAT */
case( CMD_LINSYM32 ): /* 32-bit LINNUM for a COMDAT */
return( doLINNUM( ofh, typ ) );
/* No idea what to do with these yet */
case( CMD_BAKPAT ): /* backpatch record (for Quick C) */
case( CMD_BAKPAT32 ):
case( CMD_NBKPAT ): /* named backpatch record (quick c?) */
case( CMD_NBKPAT32 ): /* 32-bit named backpatch record */
return( loadRecord( ofh ) );
case( CMD_RHEADR ): /* These records are simply ignored */
case( CMD_REGINT ): /****************************************/
case( CMD_REDATA ):
case( CMD_RIDATA ):
case( CMD_OVLDEF ):
case( CMD_ENDREC ):
case( CMD_BLKDEF ): /* block definition record */
case( CMD_BLKDEF32 ): /* weird extension for QNX MAX assembler*/
case( CMD_BLKEND ): /* block end record */
case( CMD_BLKEND32 ): /* _might_ be used by QNX MAX assembler */
case( CMD_DEBSYM ):
case( CMD_LHEADR ):
case( CMD_PEDATA ):
case( CMD_PIDATA ):
case( CMD_LOCSYM ):
case( CMD_LIBHED ):
case( CMD_LIBNAM ):
case( CMD_LIBLOC ):
case( CMD_LIBDIC ):
case( CMD_ALIAS ): /* alias definition record */
case( CMD_VERNUM ): /* TIS version number record */
case( CMD_VENDEXT ): /* TIS vendor extension record */
case( CMD_TYPDEF ): /* type definition record */
case( CMD_THEADR ): /* additonal header record */
return( loadRecord( ofh ) );
default:
return( ORL_ERROR );
}
}
orl_return OmfLoadFileStructure( omf_file_handle ofh )
{
orl_return err = ORL_OKAY;
omf_rectyp *typ;
assert( ofh );
setInitialData( ofh );
typ = _ClientRead( ofh, 1 );
if( !typ || ( *typ != CMD_THEADR ) ) return( ORL_ERROR );
ofh->last_rec = *typ;
err = doTHEADR( ofh );
if( err != ORL_OKAY ) return( err );
for( ;; ) {
typ = _ClientRead( ofh, 1 );
if( !typ ) {
err = ORL_ERROR;
break;
}
ofh->last_rec = *typ;
err = procRecord( ofh, *typ );
if( err != ORL_OKAY ) break;
if( ( *typ == CMD_MODEND ) || ( *typ == CMD_MODEND32 ) ) break;
}
return( err );
}
orl_return OmfParseScanTab( omf_bytes buffer, long len,
omf_scan_tab_struct *entry )
{
int wordsize;
assert( buffer );
assert( entry );
switch( buffer[0] ) {
case( DDIR_SCAN_TABLE ):
wordsize = 2;
break;
case( DDIR_SCAN_TABLE_32 ):
wordsize = 4;
break;
default:
return( ORL_ERROR );
}
len--;
buffer++;
if( len < ( 2 * wordsize + 1 ) ) return( ORL_ERROR );
entry->seg = loadIndex( &buffer, &len );
if( !entry->seg ) {
if( len < ( 2 * wordsize + 1 ) ) return( ORL_ERROR );
entry->lname = loadIndex( &buffer, &len );
if( !entry->lname ) return( ORL_ERROR );
}
if( len < ( 2 * wordsize ) ) return( ORL_ERROR );
entry->start = getUWord( buffer, wordsize );
buffer += wordsize;
entry->end = getUWord( buffer, wordsize );
return( ORL_OKAY );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -