📄 coffparse.cpp
字号:
// 46-47 Unsigned character
// Memory page number
//
// Parameters:
// buffer: input
// kCOFF_MaxBufferSize bytes of data that contains the raw COFF.
// ptr: input
// Current byte-offset pointer within the buffer. It must point to
// the first sections header. 0 means first byte of buffer.
// sectionsCount: input
// Total number of sections present within this COFF file.
// dspAddr: output
// Array to store the starting DSP address for each section.
// size: output
// Array to store the size for each section.
// data: output
// Array to store the pointer to actual data.
// loadableSections: output
// Number of loadable sections present within the COFF.
// Note that this value is returned from this function.
//
// Return values:
// error codes
//
// NOTE:
// buffer and all output must be allocated at the same level. For
// example, if buffer is deallocated, data will be pointing to invalid
// memory location. Therefore, always allocate/deallocate them at the
// same time.
//
int ParseCoff2Sections
(
char *buffer, UINT32 ptr, UINT16 sectionsCount,
UINT32 dspAddr[], UINT32 size[], UINT32 *data[], UINT32 *loadableSections
)
{
char *sectName;
INT32 addrPhysical;
INT32 addrVirtual;
INT32 sectSize;
INT32 ptr2Data;
INT32 ptr2Reloc;
INT32 ptr2LineNumbers;
UINT32 relocCount;
UINT32 lineNumberCount;
UINT32 flags;
INT32 cnt, idx;
idx = 0; // index for loadable sections
for (cnt=0; cnt<(INT32)sectionsCount; cnt++)
{
sectName = (char *)(buffer + ptr); ptr += 8;
addrPhysical =*(INT32 *)(buffer + ptr); ptr += 4;
addrVirtual =*(INT32 *)(buffer + ptr); ptr += 4;
sectSize =*(INT32 *)(buffer + ptr); ptr += 4;
ptr2Data =*(INT32 *)(buffer + ptr); ptr += 4;
ptr2Reloc =*(INT32 *)(buffer + ptr); ptr += 4;
ptr2LineNumbers =*(INT32 *)(buffer + ptr); ptr += 4;
relocCount =*(UINT32 *)(buffer + ptr); ptr += 4;
lineNumberCount =*(UINT32 *)(buffer + ptr); ptr += 4;
flags =*(UINT32 *)(buffer + ptr); ptr += 4;
ptr += 2; // reserved
ptr += 2; // mem page number
// if size is 0, nothing to do
if ( sectSize == 0)
continue;
// if the ptr2Data is 0, it should not be loadable
if ( ptr2Data == 0)
continue;
// if the type is not loadable, then skip section
if
(
( flags & STYP_DSECT ) // dummy
| ( flags & STYP_NOLOAD ) // no load
| ( flags & STYP_BSS ) // BSS
)
continue;
if
(
!(
(flags == STYP_REG) || (flags & STYP_PAD) ||
(flags & STYP_TEXT) || (flags & STYP_DATA)
)
)
continue;
// what remains are loadable sections. record them.
if ( flags & STYP_COPY )
{
// STYP_COPY is messy
while( 1 )
{
sectSize = *(UINT32 *)(buffer + ptr2Data);
ptr2Data += sizeof (UINT32);
addrVirtual = *(UINT32 *)(buffer + ptr2Data);
ptr2Data += sizeof (UINT32);
// if size is 0, nothing to do
if ( sectSize == 0)
break;
dspAddr[idx] = addrVirtual;
size[idx] = sectSize;
data[idx] = (UINT32 *)(buffer + ptr2Data);
idx++;
ptr2Data += sectSize * sizeof (UINT32);
}
}
else
{
// what remains are loadable sections. record them.
dspAddr[idx] = addrVirtual;
size[idx] = sectSize;
data[idx] = (UINT32 *)(buffer + ptr2Data);
idx++;
}
}
*loadableSections = idx;
return e_Err_NoError;
}
////////////////////////////////////////////////////////////////////////////////
// int ParseCoff
//
// Description:
// Parses raw COFF file and returns the result in array.
// Following is the description of the file header. Offsets are in bytes.
// 0-1 Unsigned short integer
// COFF 0: Contains magic number (093h) to indicate the file can be
// executed in a TMS320C3x/C4x system.
// COFF 1 and 2: Contains COFF version number, either 0c1h (COFF1)
// or 0c2h (COFF 2).
// 2-3 Unsigned short integer
// Number of section headers
// 4-7 Long integer
// Time and date stamp; indicates when the file was created
// 8-11 Long integer
// File pointer; contains the symbol table抯 starting address
// 12-15 Long integer
// Number of entries in the symbol table
// 16-17 Unsigned short integer
// Number of bytes in the optional header. This field is either 0 or
// 28; if it is 0, there is no op-tional file header.
// 18-19 Unsigned short integer
// Flags (see Table A-2 in spru035)
// 20-21 Unsigned short integer
// Included for COFF 1 and 2 only. Contains magic number (093h) to
// indicate the file can be executed in a TMS320C3x/C4x system.
//
// Parameters:
// filename: input
// COFF file name string.
// buffer: output
// kCOFF_MaxBufferSize bytes of array to hold COFF file.
// dspAddr: output
// Array to store the starting DSP address for each section.
// size: output
// Array to store the size (in words) for each section.
// data: output
// Array to store the pointer to actual data (derived from buffer).
// loadableSections: output
// Number of loadable sections present within the COFF.
// Note that this value is returned from this function.
//
// Return values:
// error codes
//
// NOTE:
// buffer and all output must be allocated at the same level. For
// example, if buffer is deallocated, data will be pointing to invalid
// memory location. Therefore, always allocate/deallocate them at the
// same time.
// If there is COFF3, COFF4, COFF314, etc., each can be added by using
// the case statement below and adding functions such as
// ParseCoff314Sections.
//
int ParseCoff
(
char *filename, char *buffer,
UINT32 dspAddr[], UINT32 size[], UINT32 *data[], UINT32 *loadableSections
)
{
UINT32 ptr = 0;
UINT16 coffType;
UINT16 sectionsCount;
UINT32 timeDateStamp;
UINT32 symbolTablePointer;
UINT32 symbolEntriesCount;
UINT16 optionalHeaderBytesCount;
UINT16 flags;
UINT16 coff12MagicNumber;
// fill up the buffer. this is now using ANSI
FILE *fp;
fp = fopen(filename, "rb");
if ( fp == NULL )
return e_Err_FileNotFound;
fread(buffer, sizeof(char), kCOFF_MaxBufferSize / sizeof(char), fp);
fclose(fp);
// get the params from the buffer
coffType = *(UINT16 *)(buffer + ptr); ptr += 2;
sectionsCount = *(UINT16 *)(buffer + ptr); ptr += 2;
timeDateStamp = *(UINT32 *)(buffer + ptr); // can ignore
ptr += 4;
symbolTablePointer = *(UINT32 *)(buffer + ptr); // can ignore
ptr += 4;
symbolEntriesCount = *(UINT32 *)(buffer + ptr); // can ignore
ptr += 4;
optionalHeaderBytesCount = *(UINT16 *)(buffer + ptr); ptr += 2;
flags = *(UINT16 *)(buffer + ptr); ptr += 2;
// start error checking
if ( ! ( flags | 2 ) ) // is not executable
return e_Err_CoffTypeError;
if ( sectionsCount > kCOFF_MaxNumberOfSections )
return e_Err_CoffSectionsError;
// parse sections depending on COFF file type
switch(coffType)
{
case 0xC1: // COFF1
//coff12MagicNumber = 0x93 means it is C3x/C4x executable
coff12MagicNumber = *(UINT16 *)(buffer + ptr); ptr += 2;
// COFF1 is same as COFF0 except for magic number, so NO BREAK!!!
case 0x93: // COFF0
// skip optional header
ptr += optionalHeaderBytesCount;
return ParseCoff01Sections
(
buffer, ptr, sectionsCount,
dspAddr, size, data, loadableSections
);
break;
case 0xC2: // COFF2
//coff12MagicNumber = 0x93 means it is C3x/C4x executable
coff12MagicNumber = *(UINT16 *)(buffer + ptr); ptr += 2;
// skip optional header
ptr += optionalHeaderBytesCount;
return ParseCoff2Sections
(
buffer, ptr, sectionsCount,
dspAddr, size, data, loadableSections
);
break;
default:
return e_Err_CoffTypeError;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -