⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coffparse.cpp

📁 The PCI Local bus concept was developed to break the PC data I/O bottleneck and clearly opens the d
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//		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 + -