📄 coffparse.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// coffParse.cpp
//
// Description:
// Parses any and all COFF files and returns values that can be used to
// download to the DSP. From external function, call ParseCoff.Then, it
// returns the following.
// - DSP address where the code should be loaded
// - Number of words to load
// - Data to load
// - Number of sections to be loaded
//
// Revision History:
// 2001-11-06: mik
// Created
// 2002-03-05: mik
// Fixed the loading of dummy section.
// 2002-03-06: mik
// Removed UINT8. basetsd.h from MS screws things up!
// 2002-04-17: mik
// Shuffled #define paths to reflect directory changes.
//
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "coffparse.h"
#include "../common_ddk/sierrors.h"
////////////////////////////////////////////////////////////////////////////////
// int COFF_DebugWriteToFile
//
// Description:
// Parses a coff file and writes the result into easily readable text
// format. This is useful for debugging and determining what type of COFF
// file is being used.
//
// Parameters:
// coffFile: string to the name of the COFF file to parse.
// textFile: string to the name of the text file to generate.
//
// Return values:
// error codes
//
int COFF_DebugWriteToFile
(
char *coffFile, char *textFile
)
{
char buffer[kCOFF_MaxBufferSize];
UINT32 dspAddr[kCOFF_MaxNumberOfSections];
UINT32 size[kCOFF_MaxNumberOfSections];
UINT32 *data[kCOFF_MaxNumberOfSections];
UINT32 loadableSections;
int error;
FILE *fp;
error = ParseCoff(coffFile, buffer, dspAddr, size, data, &loadableSections);
if (error != e_Err_NoError)
return error;
fp = fopen(textFile, "wt");
if (fp == NULL)
return e_Err_FileNotFound;
for (UINT32 cnt=0; cnt<loadableSections; cnt++)
{
fprintf(fp, "DSP ADDR = 0x%x\n", dspAddr[cnt]);
fprintf(fp, "Section Size = %d\n", size[cnt]);
for (UINT32 cnt1=0; cnt1<size[cnt]; cnt1++)
fprintf(fp, " 0x%x", data[cnt][cnt1]);
fprintf(fp, "\n\n");
}
fclose (fp);
return e_Err_NoError;
}
////////////////////////////////////////////////////////////////////////////////
// int ParseCoff01Sections
//
// Description:
// Parses COFF sections after the header and optional header are
// determined. After parsing, all relevant data are stored in the array.
//
// Applicable to COFF0 and COFF1
// 0-7 Character
// 8-character section name, padded with nulls
// 8-11 Long integer
// Section抯 physical address
// 12-15 Long integer
// Section抯 virtual address
// 16-19 Long integer
// Section size in words
// 20-23 Long integer
// File pointer to raw data
// 24-27 Long integer
// File pointer to relocation entries
// 28-31 Long integer
// File pointer to line number entries
// 32-33 Unsigned short integer
// Number of relocation entries
// 34-35 Unsigned short integer
// Number of line number entries
// 36-37 Unsigned short integer
// Flags (see Table A-6 in spru035)
// 38 Character
// Reserved
// 39 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 ParseCoff01Sections
(
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;
UINT16 relocCount;
UINT16 lineNumberCount;
UINT16 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 =*(UINT16 *)(buffer + ptr); ptr += 2;
lineNumberCount =*(UINT16 *)(buffer + ptr); ptr += 2;
flags =*(UINT16 *)(buffer + ptr); ptr += 2;
ptr += 1; // reserved
ptr += 1; // 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
{
dspAddr[idx] = addrVirtual;
size[idx] = sectSize;
data[idx] = (UINT32 *)(buffer + ptr2Data);
idx ++;
}
}
*loadableSections = idx;
return e_Err_NoError;
}
////////////////////////////////////////////////////////////////////////////////
// int ParseCoff2Sections
//
// Description:
// Parses COFF sections after the header and optional header are
// determined. After parsing, all relevant data are stored in the array.
//
// Applicable to COFF2
// 0-7 Character
// 8-character section name, padded with nulls
// 8-11 Long integer
// Section抯 physical address
// 12-15 Long integer
// Section抯 virtual address
// 16-19 Long integer
// Section size in words
// 20-23 Long integer
// File pointer to raw data
// 24-27 Long integer
// File pointer to relocation entries
// 28-31 Long integer
// File pointer to line number entries
// 32-35 Unsigned long
// Number of relocation entries
// 36-39 Unsigned long integer
// Number of line number entries
// 40-43 Unsigned long integer
// Flags (see Table A-6 in spru035)
// 44-45 Character
// Reserved
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -