📄 coffloader.cpp
字号:
Tmem.Space = Space;
Tmem.Asize = M_SIZE16;
Tmem.Bsize = M_SIZE16;
Tmem.Length = Count;
Tmem.pData = pData;
if( m_pSdti_Intf->pMem->Write( m_Sdti_Hndl, &Tmem ) == FALSE )
return( FALSE );
return( TRUE );
}
/*F***************************************************************************
* NAME: ReadMemory( MEM_TADDR Addr, MEM_SPACE Space, TREG_16 *pData,
* DWORD Count )
*
* DESCRIPTION: Read 16 bit data to memory
*
*F***************************************************************************/
BOOL CoffLoader::ReadMemory( MEM_TADDR Addr,
MEM_SPACE Space,
TREG_16 * pData,
DWORD Count )
{
TMEM_DESC Tmem;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
Tmem.Taddr = Addr;
Tmem.Space = Space;
Tmem.Asize = M_SIZE16;
Tmem.Bsize = M_SIZE16;
Tmem.Length = Count;
Tmem.pData = pData;
if( m_pSdti_Intf->pMem->Read( m_Sdti_Hndl, &Tmem ) == FALSE )
return( FALSE );
return( TRUE );
}
/*F***************************************************************************
* NAME: ReadRegister( char * RegName, DWORD *pReg );
*
* DESCRIPTION: Read register
*
*F***************************************************************************/
BOOL CoffLoader::ReadRegister( char * RegName, DWORD *pReg )
{
TREG reg;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
if ( m_pSdti_Intf->pReg->ReadByName( m_Sdti_Hndl, RegName, ® ) == FALSE )
return( FALSE );
// We treat all registers as 32 bit values even though most are just
// 16 bit. The sdti code knows to do the right thing.
*pReg = reg.Reg32;
return( TRUE );
}
/*F***************************************************************************
* NAME: WriteRegister( char * RegName, DWORD *pReg );
*
* DESCRIPTION: Write register
*
*F***************************************************************************/
BOOL CoffLoader::WriteRegister( char * RegName, DWORD *pReg )
{
TREG reg;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
// We treat all registers as 32 bit values even though most are just
// 16 bit. The sdti code knows to do the right thing.
reg.Reg32 = *pReg;
if ( m_pSdti_Intf->pReg->WriteByName( m_Sdti_Hndl, RegName, ® ) == FALSE )
return( FALSE );
return( TRUE );
}
/*F***************************************************************************
* NAME: LoadCoff( )
*
* DESCRIPTION: Load coff file to the target and load it's symbol table.
*
*
*F***************************************************************************/
BOOL CoffLoader::LoadCoff( )
{
TREG reg;
CString entryPoint;
BOOL success = FALSE;
m_coffHndl = NULL;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
// Error checking of parameters
if ( ( !m_pSdti_Intf ) || ( !m_Sdti_Hndl ) )
return FALSE;
// Open the file and fetch all coff settings
if ( m_coffLib->COFFR_FileOpen( m_coffFileName, &m_coffOpts, &m_coffHndl ) )
{
ErrMsg( "ERROR \tFailed to Open Coff File." );
goto EXIT_COFF_LOAD;
}
// Build the symbol table
BuildSymbolTable();
// Load raw data onto processor memory
success = LoadRawData( );
if ( success )
{
reg.Reg32 = m_coffHndl->FileInfo->entry_point;
/* For string formatting purposes */
entryPoint.Format( "%x", reg.Reg32 );
if ( m_pSdti_Intf->pReg->WriteByName( m_Sdti_Hndl, "PC", ® ) == FALSE )
success = FALSE;
}
EXIT_COFF_LOAD:
// Close the coff file. This could be removed as we will cleanup
// in the destructor.
if ( m_coffHndl )
{
m_coffLib->COFFR_FileClose( m_coffHndl );
m_coffHndl = NULL;
}
return success;
}
/*F***************************************************************************
* NAME: LoadRawData( )
*
* DESCRIPTION: Load the raw coff data
*
*
*F***************************************************************************/
BOOL CoffLoader::LoadRawData( )
{
TI_SCNHDR* pSection_Hdr;
TMEM_DESC Tmem;
unsigned char* pCoff_Buffer;
long coff_buffer_size;
long total_byte_size,num_vals;
int num_sections;
short i;
BOOL success = TRUE;
CString sectionId;
CString entryPoint;
CString memAddress;
CString memLength;
// Always test for connection to prevent user calling in disconnected
// state or with NULL handles.
if( CheckConnection() == FALSE ) {
return( FALSE );
}
// Coff section size is in target bytes so convert to host bytes
coff_buffer_size = m_coffLib->LOCTOBYTE( m_coffHndl, m_coffHndl->FileInfo->largest_sect_size );
// Allocate memory for coff buffer
pCoff_Buffer = ( unsigned char* )new( char[coff_buffer_size] );
if ( ! pCoff_Buffer )
return FALSE;
// Pointer to section header
pSection_Hdr = ( TI_SCNHDR* )( m_coffHndl->FileInfo->sect_hdrs );
num_sections = m_coffHndl->FileInfo->file_hdr.f_nscns;
Message( "Loading COFF file.\r\n" );
Message( "Filename: " + m_coffFileName);
// For string formatting purposes
entryPoint.Format( "%x", m_coffHndl->FileInfo->entry_point );
while ( entryPoint.GetLength() < 8 )
entryPoint.Insert(0, "0");
Message( "File entry point: 0x" + entryPoint + "\r\n" );
// Go through each section to determine if it should be loaded
for ( i = 1 ; i <= num_sections ; i++, pSection_Hdr++ )
{
if ( m_coffLib->COFFR_IsLoadSection( m_coffHndl, i ) != COFF_NOLOADSECT_ERR )
{
m_coffLib->COFFR_GetSectData( m_coffHndl, ( short )i, pCoff_Buffer, 0,
m_coffLib->LOCTOBYTE( m_coffHndl, pSection_Hdr->s_size ),
&total_byte_size );
// Convert to target vals
num_vals = m_coffLib->BYTETOLOC(m_coffHndl,total_byte_size);
// Set parameters to write the section of the coff file
Tmem.Taddr = pSection_Hdr->s_vaddr;
Tmem.Space = ( pSection_Hdr->s_page == 0 ) ? M_PROGRAM : M_DATA;
Tmem.Asize = M_SIZE16;
Tmem.Bsize = M_SIZE8; // Our buffer is 8 bit chars for coff
Tmem.Length = num_vals;
Tmem.pData = ( void* )( pCoff_Buffer );
// Write data to memory
if ( ( success = m_pSdti_Intf->pMem->Write( m_Sdti_Hndl, &Tmem ) ) == FALSE )
break;
}/* End of COFFR_IsLoadSection */
}
if ( success == FALSE )
Message( "\t\t...FAILED." );
// Free coff buffer
delete( pCoff_Buffer );
return success;
}
/*F***************************************************************************
* NAME: BytesPerDataSize(struct SYMBOL * s)
*
* DESCRIPTION: Determine the number of bytes for a given symbol type. Just
* handles the easy cases.
*
*F***************************************************************************/
int CoffLoader::BytesPerDataSize(struct SYMBOL * s)
{
switch( s->symtype &0x0f )
{
case TI_T_LONG: /* LONG INTEGER */
case TI_T_ULONG: /* UNSIGNED LONG */
return( 4 );
// Not used in the programamer
case TI_T_FLOAT: /* SINGLE PRECISION FLOATING POINT */
case TI_T_DOUBLE: /* DOUBLE PRECISION FLOATING POINT */
case TI_T_STRUCT: /* STRUCTURE */
case TI_T_UNION: /* UNION */
case TI_T_ENUM: /* ENUMERATION */
case TI_T_LDOUBLE: /* LONG DOUBLE FLOATING POINT */
return( 0 );
case TI_T_VOID: /* VOID TYPE */
case TI_T_SCHAR: /* CHARACTER (EXPLICITLY "signed") */
case TI_T_CHAR: /* CHARACTER (IMPLICITLY SIGNED) */
case TI_T_SHORT: /* SHORT INTEGER */
case TI_T_INT: /* INTEGER */
case TI_T_UCHAR: /* UNSIGNED CHARACTER */
case TI_T_USHORT: /* UNSIGNED SHORT */
case TI_T_UINT: /* UNSIGNED INTEGER */
default:
return( 2 );
}
}
/*F***************************************************************************
* NAME: FindSymbol(char * name)
*
* DESCRIPTION: Search the symbol table for symbol name
*
*
*F***************************************************************************/
struct SYMBOL * CoffLoader::FindSymbol(char * name)
{
SYMBOL_L * n;
//Go through list from head to tail - if the name matches, return
n = m_symlist;
while (n != (SYMBOL_L *)NULL )
{
if( (strcmp(name, n->s->symname) == 0) // C name _Symbol
|| (strcmp(name+1, n->s->symname) == 0)) // asm name Symbol
break;
n = n->next;
}
if ( n!= (SYMBOL_L *)NULL )
return ( n->s );
return ((struct SYMBOL *)NULL );
}
/*F***************************************************************************
* NAME: DeleteSymbolList( void )
*
* DESCRIPTION: Delete the symbol table
*
*
*F***************************************************************************/
BOOL CoffLoader::DeleteSymbolList( void )
{
SYMBOL_L * n;
while (m_symlist != (SYMBOL_L *)NULL )
{
n = m_symlist->next;
delete(m_symlist->s->symname); m_symlist->s->symname = (char *)NULL;
delete(m_symlist->s); m_symlist->s = (struct SYMBOL *)NULL;
delete(m_symlist);
m_symlist = n;
}
return(TRUE);
}
/*F***************************************************************************
* NAME: BuildSymbolTable( void )
*
* DESCRIPTION: Build the symbol table. This is crude at best but does get
* job done for such a simple application.
*
*
*F***************************************************************************/
BOOL CoffLoader::BuildSymbolTable( void )
{
TI_SCNHDR * pSectionHdr;
long SymbolIndex;
COFF_SYMTYPE SymbolType;
TI_SYMENT SymbolEntry;
TI_AUXENT AuxEntry;
long NumSymbolsRead;
long NumSymbolsSaved = 0;
if( m_coffHndl == NULL )
return( FALSE );
// Unload old symbols before loading new symbols
if( m_symlist != NULL ) {
DeleteSymbolList();
}
// Load the string table first
m_coffLib->COFFR_LoadStrings( m_coffHndl );
SymbolIndex = 0;
NumSymbolsRead = 0;
while( SymbolIndex < m_coffHndl->FileInfo->file_hdr.f_nsyms )
{
m_coffLib->COFFR_GetSymbolTableEntry( m_coffHndl,
&SymbolIndex,
&SymbolType,
&SymbolEntry,
&AuxEntry );
switch( SymbolType )
{
case COFF_AUX_TAG:
SymbolIndex = AuxEntry.x_tag.x_endndx;
break;
case COFF_AUX_FILE:
case COFF_AUX_SECT:
case COFF_AUX_BB:
case COFF_AUX_EOS:
break;
default:
if( SymbolEntry.n_sclass == TI_C_EXT ) // The interesting symbols, globals
{
char name[256];
SYMBOL_L * new_list_elem;
struct SYMBOL * new_sym;
size_t name_length;
// Only load interesting symbols
if ( ( SymbolEntry.n_scnum < 1)
|| ( SymbolEntry.n_scnum > m_coffHndl->FileInfo->file_hdr.f_nscns))
break;
pSectionHdr = (TI_SCNHDR *)(m_coffHndl->FileInfo->sect_hdrs);
pSectionHdr += (SymbolEntry.n_scnum-1);
m_coffLib->COFFR_GetSymbolName( m_coffHndl, &SymbolEntry, 256, name );
// Allocate a new symbol, and new symbol list element. Add symbol to
// the head of the list
new_sym = (struct SYMBOL *)new( struct SYMBOL );
new_list_elem = (SYMBOL_L *)new( SYMBOL_L );
new_list_elem->s = new_sym;
new_list_elem->next = m_symlist; // New symbol at head of the list
m_symlist = new_list_elem;
// Fill in the name, address, and page info for the symbol.
name_length = (strlen(name)+1);
new_sym->symname = (char *)new( char[name_length]);
strcpy(new_sym->symname, name);
new_sym->symaddr = (unsigned long)(SymbolEntry.n_value);
new_sym->sympage = (unsigned long)(pSectionHdr->s_page);
new_sym->symtype = (unsigned long)(SymbolEntry.n_type );
new_sym->symsclass = (unsigned long)(SymbolEntry.n_sclass );
new_sym->symnumaux = (unsigned long)(SymbolEntry.n_numaux );
NumSymbolsSaved++;
} /* End Default */
break;
}/* End of switch */
} /* End of while */
m_numSymbols = NumSymbolsSaved;
return( TRUE );
}
/*F***************************************************************************
* NAME: FindSwbp(char * name)
*
* DESCRIPTION: Search the bp table for symbol name
*
*
*F***************************************************************************/
SWBP_SYMBOL * CoffLoader::FindSwbp(char * name )
{
SWBP_SYMBOL * b;
SYMBOL * sym;
//Go through list from head to tail - if the name matches, return
b = m_swbplist;
while (b != (SWBP_SYMBOL *)NULL )
{
sym = b->s;
if( (strcmp(name, sym->symname) == 0) // C name _Symbol
|| (strcmp(name+1, sym->symname) == 0)) // asm name Symbol
break;
b = b->next;
}
if ( b!= (SWBP_SYMBOL *)NULL )
return ( b );
return ((SWBP_SYMBOL *)NULL );
}
/*F***************************************************************************
* NAME: DeleteSwbpList( void )
*
* DESCRIPTION: Delete the bp table table
*
*
*F***************************************************************************/
BOOL CoffLoader::DeleteSwbpList( void )
{
SWBP_SYMBOL * b;
while (m_swbplist != (SWBP_SYMBOL *)NULL )
{
b = m_swbplist->next;
delete(m_swbplist);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -