📄 ccoffformat.cpp
字号:
//----------------------------------------------------------
//The TI COFF file format version 2
//implement by wei ren hui
//
//---------------------------------------------------------------
#ifndef _COFF_FILE_H_
#define _COFF_FILE_H_
//-----------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
//-----------------Table A?2--------------------------------------
#define F_RELFLG 0x0001 //Relocation information was stripped from the file.
#define F_EXEC 0x0002 //The file is relocatable (it contains no unresolved external references).
#define F_LNNO 0x0004 //Line numbers were stripped from the file.
#define F_LSYMS 0x0008 //Local symbols were stripped from the file.
#define F_LITTLE 0x0100 //The file has little-endian byte ordering (least significant byte first).
#define F_BIG 0x0200 //The file has big-endian byte ordering (most significant byte first).
#define F_SYMMERGE 0x1000 //Duplicate symbols were removed.
typedef struct COFF_FileHeaderV2T
{
unsigned short version_ID; //indicates version of COFF file structure
unsigned short num_sect_head; //Number_of_section_headers
long time_date_stamp; // indicates when the file was created
long symbol_fp; //contains the symbol table’s starting address
long num_entries_sym_tbl; //Number of entries in the symbol table
unsigned short size_opt_header;//Number of bytes in the optional header. this field is either 0 or 28; if it is 0, there is no optional file header.
unsigned short flags; // (see Table A?2)
unsigned short target_ID; // magic number (0097h) indicates the file can be executed in a TMS470R1x system
}
COFF_FileHeaderV2;
typedef struct OptionalFileHeaderT
{
short opt_fhd_magic_num; //Optional file header magic number (0108h)
short version_stamp;
long exe_code_size; //Size (in bytes) of executable code
long init_data_size; //Size (in bytes) of initialized data
long uinit_data_size; //Size (in bytes) of uninitialized data
long entry_point;
long exe_code_start_addr; //Beginning address of executable code
long init_data_start_addr; //Beginning address of initialized data
}OptinalFileHeader;
//---------------------------Flags (see Table A?5)
#define STYP_REG 0x00000000 //Regular section (allocated, relocated, loaded)
#define STYP_DSECT 0x00000001 //Dummy section (relocated, not allocated, not loaded)
#define STYP_NOLOAD 0x00000002 //Noload section (allocated, relocated, not loaded)
#define STYP_XXX1 0x00000004 //Reserved
#define STYP_XXX2 0x00000008 //Reserved
#define STYP_COPY 0x00000010 //Copy section (relocated, loaded, but not allocated; relocation and line number entries are processed normally)
#define STYP_TEXT 0x00000020 //Section contains executable code
#define STYP_DATA 0x00000040 //Section contains initialized data
#define STYP_BSS 0x00000080 //Section contains uninitialized data
#define STYP_BLOCK 0x00001000 //Alignment used as a blocking factor
#define STYP_PASS 0x00002000 //Section should pass through unchanged
#define STYP_CLINK 0x00004000 //Section requires conditional linking
typedef struct AddrOffT
{
long zero;
long offset;
}AddrOff;
typedef union
{
char name[8];
AddrOff addr_name;
}Name;
typedef struct SectionHeaderT
{
/*Character This field contains one of the following:
1) An 8-character section name, padded with nulls
2) A pointer into the string table if the symbol name is longer than eight characters
*/
Name section_name;
long physical_addr;//Section’s physical address
long virtual_addr;//Section’s virtual address
long sect_size;//Section size in bytes
long sect_data_fp;//File pointer to raw data
long relocat_entries_fp;//File pointer to relocation entries
long line_num_entries_fp;//File pointer to line number entries
unsigned long num_relocat_entries;//Number of relocation entries
unsigned long num_line_number_entries;//Number of line number entries
unsigned long flag;//Flags (see Table A?5)
unsigned short reserved;
unsigned short mem_page_num;//Memory page number
}SectionHeader;
//-------------------------Relocation type (see Table A?7)
#define R_RELLONG 0x0011 //32-bit direct reference to symbol’s address
#define R_PCR23H 0x0016 //23-bit PC-relative reference to a symbol’s address, in halfwords (divided by 2)
#define R_PCR24W 0x0017 //24-bit PC-relative reference to a symbol’s address, in words (divided by 4)
typedef struct RelocationEntryT
{
long virual_addr_ref;// Virtual address of the reference
unsigned short sym_tbl_ind;//Symbol table index (0?65 535)
unsigned short reserved;
unsigned short relocat_type;//Relocation type (see Table A?7)
}RelocationEntry;
typedef struct LineNumTableT
{
unsigned long addr_or_sym_idx;
unsigned short line_number;
}LineNumTable;
//---------------------Table A?10. Symbol Storage Classes
#define C_NULL 0 //No storage class
#define C_AUTO 1 //Reserved
#define C_EXT 2 //External definition
#define C_STAT 3 //Static
#define C_REG 4 //Reserved
#define C_EXTREF 5 //External reference
#define C_LABEL 6 //Label
#define C_ULABEL 7 //Undefined label
#define C_MOS 8 //Reserved
#define C_ARG 9 //Reserved
#define C_STRTAG 10 //Reserved
#define C_MOU 11 //Reserved
#define C_UNTAG 12 //Reserved
#define C_TPDEF 13 //Reserved
#define C_USTATIC 14 //Undefined static
#define C_ENTAG 15 //Reserved
#define C_MOE 16 //Reserved
#define C_REGPARM 17 //Reserved
#define C_FIELD 18 //Reserved
#define C_UEXT 19 //Tentative external definition
#define C_STATLAB 20 //Static load time label
#define C_EXTLAB 21 //External load time label
#define C_VARARG 27 //Last declared parameter of a function with variable number of arguments
#define C_BLOCK 100 //Reserved
#define C_FCN 101 //Reserved
#define C_EOS 102 //Reserved
#define C_FILE 103 //Reserved
#define C_LINE 104 //Used only by utility programs
//------------------Table
typedef struct SymbolTableT
{
/*0?7 Character This field contains one of the following:
1) An 8-character symbol name, padded with nulls
2) A pointer into the string table if the symbol name is longer than eight characters
*/
Name symbol_name;
long symbol_value;// storage class dependent
short sect_num_symbol;//section number of the symbol
unsigned short bs_derive_type;// Basic and derived type specification
char storage_class;//Character Storage class of the symbol Table A?10. Symbol Storage Classes
char num_aux_entries;//Character Number of auxiliary entries (always 0 or 1)
}SymbolTable;
typedef struct AuxiliarTableEntriesT
{
int sect_len;//Integer Section length
unsigned short num_relocat_entries;//Number of relocation entries
unsigned short num_line_num_entries;//Number of line number entries
unsigned char reserved[10];//— Not used (zero filled)
}AuxiliarTableEntries;
//////////////////////////////////////////////////////////////////////////
typedef struct CoffSectionT
{
SectionHeader sect_hd;
char* sect_name;
unsigned char* sect_data;
RelocationEntry* relocate_entry;
}CoffSection;
typedef struct CoffSymbolT
{
SymbolTable sym_tbl;
AuxiliarTableEntries *aux_tbl;
char* sym_name;
}CoffSymbol;
typedef struct StringTableT
{
long str_len;
char* data_ptr;
}StringTable;
//-------------------------------------------------------
void DumpCoff(char* coff_file);
int Coff2Raw(char* bin_file, char* coff_file);
//------------------------------------------------------
// List operation
//------------------------------------------------------
//------------------------------------------------------------
// following is operation on TI COFF version 2.0
//------------------------------------------------------------
class CCOFFV2
{
public:
CCOFFV2();
~CCOFFV2();
int LoadCoffFile(char* coff_file);
bool IsCoffTMS(void);
COFF_FileHeaderV2* GetCoffHeader(void);
unsigned short GetVersionID(void);
SectionHeader* GetSectionHeader(int idx);
SymbolTable* GetSymbalTable(int idx);
bool IsSpecialSection(int idx);
void DisplayCoffInfo(void);
bool COFF2Bin(char* bin_file);
protected:
COFF_FileHeaderV2 m_coffFileHeader;
OptinalFileHeader *m_pOptFileHeader;
LineNumTable *m_pLineNumTable;
StringTable *m_pStringTable;
CoffSection *m_sections;
CoffSymbol *m_symbol;
protected:
void ClearCoffContext(void);
void Disp_CoffHeader(COFF_FileHeaderV2* file_hd);
void Disp_OptionalHeader(OptinalFileHeader* opt_f_hd);
void Disp_AuxiliarTableEntries(AuxiliarTableEntries * aux_tbl_entry);
void Disp_RelocationEntry(RelocationEntry * rel_entry);
void Disp_SymbolTable(SymbolTable * sym_tbl);
void Disp_StringTable(StringTable * str_tbl);
void Disp_SectionHeader(SectionHeader * sect_hd);
private:
bool m_load_ok;
};
CCOFFV2::CCOFFV2()
{
memset(&m_coffFileHeader,0,sizeof(COFF_FileHeaderV2));
m_pOptFileHeader=NULL;
m_pLineNumTable=NULL;
m_pStringTable=NULL;
m_symbol=NULL;
m_sections=NULL;
m_load_ok = false;
}
CCOFFV2::~CCOFFV2()
{
ClearCoffContext();
}
int CCOFFV2::LoadCoffFile(char* coff_file)
{
FILE* fp_coff = NULL;
unsigned int block_read = 0;
int i = 0;
SectionHeader * ptrSectHd = NULL;
SymbolTable* ptrSymTbl = NULL;
CoffSection *ptrCofSec = NULL;
CoffSymbol *ptrCofSym = NULL;
char ptr_data = NULL;
long string_size;
if(m_load_ok)
{
ClearCoffContext();
}
fp_coff = fopen(coff_file, "rb");
if(fp_coff == NULL)
{
printf("cannot open file %s\n",coff_file);
return -1;
}
// read file header
block_read=fread(&m_coffFileHeader,sizeof(COFF_FileHeaderV2),1,fp_coff);
if(block_read != 1)
{
printf("error read file header\n");
fclose(fp_coff);
return -2;
}
// if exist optional file header then read the optional file header
if(m_coffFileHeader.size_opt_header!=0)
{
m_pOptFileHeader = (OptinalFileHeader*)malloc(sizeof(OptinalFileHeader));
block_read=fread(m_pOptFileHeader,sizeof(OptinalFileHeader),1,fp_coff);
if(block_read != 1)
{
printf("error read optinoal file header\n");
fclose(fp_coff);
return -2;
}
}
// allocate memory for storing section headers
m_sections = (CoffSection*)malloc(sizeof(CoffSection)*m_coffFileHeader.num_sect_head);
if(m_sections==NULL)
{
printf("error malloc section space\n");
free(m_pOptFileHeader);
fclose(fp_coff);
return -3;
}
// allocate memory for storing symbal tables
m_symbol = (CoffSymbol*)malloc(sizeof(CoffSymbol)*m_coffFileHeader.num_entries_sym_tbl);
if(m_symbol==NULL)
{
printf("error malloc symbol space\n");
free(m_sections);
free(m_pOptFileHeader);
m_pOptFileHeader = NULL;
m_sections=NULL;
fclose(fp_coff);
return -3;
}
//fill allocated memory with zero
memset(m_sections,0,sizeof(CoffSection)*m_coffFileHeader.num_sect_head);
memset(m_symbol,0,sizeof(CoffSymbol)*m_coffFileHeader.num_entries_sym_tbl);
// read section headers
for(i = 0; i< m_coffFileHeader.num_sect_head; i++)
{
fread(&m_sections[i].sect_hd,sizeof(SectionHeader),1,fp_coff);
}
// read symbal tables
fseek(fp_coff,m_coffFileHeader.symbol_fp,SEEK_SET);
for(i = 0; i< m_coffFileHeader.num_entries_sym_tbl; i++)
{
fread(&m_symbol[i],sizeof(SymbolTable),1,fp_coff);
if(m_symbol[i].sym_tbl.num_aux_entries!=0)
{
m_symbol[i].aux_tbl = (AuxiliarTableEntries*)malloc(m_symbol[i].sym_tbl.num_aux_entries*sizeof(AuxiliarTableEntries));
fread(&m_symbol[i].aux_tbl,m_symbol[i].sym_tbl.num_aux_entries*sizeof(AuxiliarTableEntries),1,fp_coff);
}
}
// allocate memory for each section data
for(i = 0; i< m_coffFileHeader.num_sect_head; i++)
{
m_sections[i].sect_data = (unsigned char*)malloc(m_sections[i].sect_hd.sect_size);
fseek(fp_coff,m_sections[i].sect_hd.sect_data_fp,SEEK_SET);
fread(m_sections[i].sect_data,m_sections[i].sect_hd.sect_size,1,fp_coff);
if(m_sections[i].sect_hd.num_relocat_entries>0)
{
m_sections[i].relocate_entry=(RelocationEntry*)malloc(sizeof(RelocationEntry)*m_sections[i].sect_hd.num_relocat_entries);
fseek(fp_coff,m_sections[i].sect_hd.relocat_entries_fp,SEEK_SET);
fread(m_sections[i].relocate_entry,sizeof(RelocationEntry),m_sections[i].sect_hd.num_relocat_entries,fp_coff);
}
if(m_sections[i].sect_hd.section_name.name==NULL)
{
fseek(fp_coff,m_sections[i].sect_hd.section_name.addr_name.offset,SEEK_SET);
fread(&string_size,4,1,fp_coff);
m_sections[i].sect_name = (char*)malloc(string_size);
fread(m_sections[i].sect_name,string_size,1,fp_coff);
}
}
for(i = 0; i< m_coffFileHeader.num_entries_sym_tbl; i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -