📄 cofflib.cpp
字号:
SEEK_SET))
|| ( fread( pOptHdr, ReadSize, SIZE_ONE, pCoffHndl->FileHndl)
!= SIZE_ONE) )
{
return (COFF_FILE_ACCESS_ERR);
}
if (pCoffHndl->FileInfo->byte_swapped)
{
swap2byte(&pOptHdr->magic);
swap2byte(&pOptHdr->vstamp);
swap4byte(&pOptHdr->tsize);
swap4byte(&pOptHdr->dsize);
swap4byte(&pOptHdr->bsize);
swap4byte(&pOptHdr->entrypt);
swap4byte(&pOptHdr->text_start);
swap4byte(&pOptHdr->data_start);
}
pCoffHndl->FileInfo->entry_point = pOptHdr->entrypt;
}
return ( 0 );
}
/*F***************************************************************************
* NAME: COFF_RET
* COFFR_GetSectionHdr( COFF_HNDL pCoffHndl,
* short SectNum,
* SCNHDR * pSectHdr)
*
* DESCRIPTION: Read in the COFF section header information.
*
* INPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* OUTPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* RETURN:
*
* NOTES:
*
*F***************************************************************************/
COFF_RET
CoffLib::COFFR_GetSectionHdr( COFF_HNDL pCoffHndl,
short SectNum,
TI_SCNHDR * pSectHdr)
{
TI_O_SCNHDR o_secthead;
int err;
long FilePos;
int SectionSize;
if ( ( SectNum < 1 )
|| ( SectNum > (short)pCoffHndl->FileInfo->file_hdr.f_nscns ))
{
return (COFF_BAD_SECT_NUM_ERR);
}
/*----------------------------------------------------------------------*/
/* READ IN SECTION HEADER. */
/*----------------------------------------------------------------------*/
SectionSize = TI_SCNHSZ_IN(pCoffHndl->FileInfo->coff_version);
FilePos = (long)TI_FILHSZ_IN(pCoffHndl->FileInfo->coff_version)
+ pCoffHndl->FileInfo->file_hdr.f_opthdr
+ (( SectionSize ) * (SectNum - 1));
if ( (fseek(pCoffHndl->FileHndl, FilePos, SEEK_SET)))
{
return (COFF_FILE_ACCESS_ERR);
}
if ( TI_ISCOFF_2( pCoffHndl->FileInfo->coff_version ) )
{
err = fread( pSectHdr, SectionSize, SIZE_ONE, pCoffHndl->FileHndl);
}
else
{
err = fread( &o_secthead, SectionSize, SIZE_ONE, pCoffHndl->FileHndl);
}
if ( err != SIZE_ONE )
{
return (COFF_FILE_ACCESS_ERR);
}
/*----------------------------------------------------------------------*/
/* SWAP SECTION HEADER IF REQUIRED. LOOK FOR BSS AND CINIT SECTIONS. */
/*----------------------------------------------------------------------*/
if ( pCoffHndl->FileInfo->byte_swapped )
{
if( TI_ISCOFF_2(pCoffHndl->FileInfo->coff_version ))
{
if ( pSectHdr->s_zeroes == 0L )
{
swap4byte(&pSectHdr->s_offset);
}
swap4byte(&pSectHdr->s_paddr);
swap4byte(&pSectHdr->s_vaddr);
swap4byte(&pSectHdr->s_size);
swap4byte(&pSectHdr->s_scnptr);
swap4byte(&pSectHdr->s_relptr);
swap4byte(&pSectHdr->s_lnnoptr);
swap4byte(&pSectHdr->s_nreloc);
swap4byte(&pSectHdr->s_nlnno);
swap4byte(&pSectHdr->s_flags);
swap2byte(&pSectHdr->s_page);
}
else
{
swap4byte(&o_secthead.os_paddr);
swap4byte(&o_secthead.os_vaddr);
swap4byte(&o_secthead.os_size);
swap4byte(&o_secthead.os_scnptr);
swap4byte(&o_secthead.os_relptr);
swap4byte(&o_secthead.os_lnnoptr);
swap2byte(&o_secthead.os_nreloc);
swap2byte(&o_secthead.os_nlnno);
swap2byte(&o_secthead.os_flags);
}
}
if ( !TI_ISCOFF_2( pCoffHndl->FileInfo->coff_version ))
{
strncpy( pSectHdr->s_name, o_secthead.os_name, TI_SYMNMLEN );
pSectHdr->s_paddr = o_secthead.os_paddr;
pSectHdr->s_vaddr = o_secthead.os_vaddr;
pSectHdr->s_size = o_secthead.os_size;
pSectHdr->s_scnptr = o_secthead.os_scnptr;
pSectHdr->s_relptr = o_secthead.os_relptr;
pSectHdr->s_lnnoptr = o_secthead.os_lnnoptr;
pSectHdr->s_nreloc = o_secthead.os_nreloc;
pSectHdr->s_nlnno = o_secthead.os_nlnno;
pSectHdr->s_flags = o_secthead.os_flags;
pSectHdr->s_page = o_secthead.os_page;
}
if ( (pSectHdr->s_flags & TI_STYP_COPY)
&& !strcmp(pSectHdr->s_name, TI_CINIT) )
{
pCoffHndl->FileInfo->cinit_sect = SectNum;
}
if ( (pSectHdr->s_flags & TI_STYP_BSS)
&& !strcmp(pSectHdr->s_name, TI_BSS) )
{
pCoffHndl->FileInfo->bss_sect = SectNum;
}
return ( 0 );
}
/*F***************************************************************************
* NAME: COFF_RET
* COFFR_IsLoadSection( COFF_HNDL pCoffHndl, short SectNum )
*
*
* DESCRIPTION: Determine if the section is a loadable section.
*
* INPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* OUTPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* RETURN:
*
* NOTES:
*
*F***************************************************************************/
COFF_RET
CoffLib::COFFR_IsLoadSection( COFF_HNDL pCoffHndl, short SectNum )
{
TI_SCNHDR * pSectHdr = SECT_HDR_PTR( SectNum );
if ( ( SectNum > 0 )
&& ( SectNum <= pCoffHndl->FileInfo->file_hdr.f_nscns )
&& ( pSectHdr->s_scnptr != 0 )
&& ( pSectHdr->s_size !=0 )
&& !( pSectHdr->s_flags & TI_STYP_DSECT )
&& !( pSectHdr->s_flags & TI_STYP_COPY )
&& !( pSectHdr->s_flags & TI_STYP_NOLOAD ))
return( 0 ); /* Load Section */
else
return( COFF_NOLOADSECT_ERR ); /* No Load Section */
}
/*F***************************************************************************
* NAME: COFF_RET
* COFFR_FindMaxLoadSectionSize( COFF_HNDL pCoffHndl,
* long * pMaxSizeInBytes )
*
* DESCRIPTION: Find the size of the biggest section and return the size
* in host byte count.
*
* INPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* OUTPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* RETURN:
*
* NOTES:
*
*F***************************************************************************/
COFF_RET
CoffLib::COFFR_FindMaxLoadSectionSize( COFF_HNDL pCoffHndl,
long * pMaxSizeInBytes )
{
int i;
long MaxSize;
TI_SCNHDR * pSectHdr = SECT_HDR_PTR( 1 );
MaxSize = 0;
for( i=1; i<=pCoffHndl->FileInfo->file_hdr.f_nscns; i++ )
{
if ( COFFR_IsLoadSection( pCoffHndl, (short)i )
!= COFF_NOLOADSECT_ERR )
{
if( pSectHdr->s_size > MaxSize )
MaxSize = pSectHdr->s_size;
}
pSectHdr++;
}
/* Convert s_size to number of bytes in the largest section */
*pMaxSizeInBytes = LOCTOBYTE( pCoffHndl, MaxSize);
return( 0 );
}
/*F***************************************************************************
* NAME: COFF_RET
* COFFR_GetSectData( COFF_HNDL pCoffHndl,
* short SectNum,
* unsigned char * pRetBuffer,
* unsigned long ByteOffset,
* long BytesToRead,
* long * pActualBytesRead )
*
* DESCRIPTION: Read in section data from the file.
*
* INPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* OUTPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* RETURN:
*
* NOTES:
*
*F***************************************************************************/
COFF_RET
CoffLib::COFFR_GetSectData( COFF_HNDL pCoffHndl,
short SectNum,
unsigned char * pRetBuffer,
unsigned long ByteOffset,
long BytesToRead,
long * pActualBytesRead )
{
unsigned long FilePos;
long BytesLeftInSection,BytesLeftToRead,BytesRead;
TI_SCNHDR * pSectHdr = SECT_HDR_PTR( SectNum );
/*- Set file position and seek -----------------------------------------*/
FilePos = pSectHdr->s_scnptr + ByteOffset;
if ( fseek(pCoffHndl->FileHndl, FilePos, SEEK_SET))
return (COFF_FILE_ACCESS_ERR);
/*- Read min of bytes left in section or requested bytes ---------------*/
BytesLeftInSection = LOCTOBYTE( pCoffHndl, pSectHdr->s_size) - ByteOffset;
if( BytesLeftInSection <= 0 )
return( COFF_LOAD_SIZE_ERR );
BytesLeftToRead = MIN(BytesLeftInSection, BytesToRead );
/*- Read the bytes -----------------------------------------------------*/
BytesRead = fread( pRetBuffer,sizeof(unsigned char),
BytesLeftToRead,
pCoffHndl->FileHndl);
/*- Return number of bytes read and error if less then fread request ---*/
*pActualBytesRead = BytesRead;
if( BytesRead != BytesLeftToRead )
return ( COFF_LOAD_SIZE_ERR );
else
return( 0 );
}
/*F***************************************************************************
* NAME: COFF_RET COFFR_LoadStrings( COFF_HNDL pCoffHndl )
*
* DESCRIPTION: Read in the string table.
*
* INPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* OUTPUTS:
* PARAMETERS:
*
* GLOBALS:
*
* RETURN:
*
* NOTES:
*
*F***************************************************************************/
COFF_RET
CoffLib::COFFR_LoadStrings( COFF_HNDL pCoffHndl )
{
unsigned long read_str_size; /* SIZE OF STRING TABLE */
unsigned long bufsize; /* SIZE OF CURRENT BUFFER */
unsigned int ntoread; /* AMOUNT TO READ FROM FILE */
unsigned long excess; /* AMOUNT LEFT OVER FROM LAST BUFFE*/
STRTAB *packet; /* STRING TABLE BUFFER PACKET */
/*----------------------------------------------------------------------*/
/* FREE ANY PREVIOUS STRING BUFFERS */
/*----------------------------------------------------------------------*/
FreeStrings( pCoffHndl );
/*----------------------------------------------------------------------*/
/* THE STRING TABLE IS READ IN AS A LINKED LIST OF BUFFERS. TO */
/* PREVENT NAMES FROM BEING SPLIT ACROSS MULTIPLE BUFFERS, ANY PARTIAL */
/* NAME AT THE END OF A BUFFER IS COPIED intO THE BEGINNING OF THE */
/* NEXT BUFFER. THE VARIABLE 'EXCESS' KEEPS TRACK OF HOW MUCH NEEDS */
/* TO BE COPIED FROM THE PREVIOUS BUFFER. */
/*----------------------------------------------------------------------*/
read_str_size = pCoffHndl->FileInfo->str_size - sizeof(long);
/* SUBTRACT OFF BYTES ALREADY READ */
excess = 0; /* INITIALIZE LAST-BUFFER OVERFLOW */
/*----------------------------------------------------------------------*/
/* SEEK TO THE FIRST STRING ENTRY. */
/*----------------------------------------------------------------------*/
if( fseek( pCoffHndl->FileHndl,
( pCoffHndl->FileInfo->file_hdr.f_symptr
+(pCoffHndl->FileInfo->file_hdr.f_nsyms*TI_SYMESZ
+sizeof(long))), SEEK_SET))
{
return (COFF_FILE_ACCESS_ERR);
}
/*----------------------------------------------------------------------*/
/* READ STRING BUFFERS UNTIL THE WHOLE STRING TABLE IS READ. */
/*----------------------------------------------------------------------*/
while (read_str_size)
{
/*------------------------------------------------------------------*/
/* ALLOCATE A NEW BUFFER. ON 16-BIT MACHINES, RESTRICT THE */
/* BUFFER SIZE TO THE MAXIMUM THAT CAN BE ALLOCATED AT ONCE. */
/*------------------------------------------------------------------*/
bufsize = MIN(read_str_size + excess, COFF_MAX_STRING_ALLOC);
packet = (STRTAB *) malloc(sizeof(STRTAB)+(size_t)bufsize);
if ( packet == (STRTAB *)NULL )
return ( COFF_MALLOC_ERR );
memset( packet, 0, sizeof(STRTAB)+(size_t)bufsize );
/*------------------------------------------------------------------*/
/* COPY ANY PARTIAL STRING FROM THE LAST BUFFER into THIS ONE. */
/* THEN FILL THE REST OF THE BUFFER BY READING FROM THE FILE. */
/*------------------------------------------------------------------*/
if ( excess )
{
strncpy( packet->buf,
( pCoffHndl->FileInfo->str_head->buf
+ pCoffHndl->FileInfo->str_head->size),
(int)excess);
}
ntoread = (unsigned int)(bufsize - excess);
if (fread( packet->buf+excess,(size_t)ntoread,SIZE_ONE,
pCoffHndl->FileHndl )!= SIZE_ONE)
{
return ( COFF_FILE_ACCESS_ERR );
}
read_str_size -= ntoread;
/*------------------------------------------------------------------*/
/* IF THE BUFFER ENDS IN A PARTIAL STRING (DOESN'T END IN NULL), */
/* KEEP TRACK OF HOW MANY CHARACTERS ARE IN THE PARTIAL STRING */
/* SO THEY CAN BE COPIED intO THE NEXT BUFFER. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -