📄 armsym.c
字号:
/* armsym.c -- Main instruction emulation: SA11x Instruction Emulator.
Copyright (C) 2001 Princeton University
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <assert.h>
#include "bfd.h"
#include <search.h>
#include "armsym.h"
#include "armdefs.h"
static char itoa_tab[16] =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
'f' };
static long storage_needed;
static asymbol **symbol_table;
static unsigned long number_of_symbols, kernel_number;
static SYM_FUNC trap_sym = { "Trap", 0, 0, 0 };
static SYM_FUNC init_sym = { "Init", 0, 0, 0 }; /* <tktan> BUG200103311736 */
static FUNC_NODE init_node = { &init_sym, 0, 0, 0 };
static ARMword debug;
#if 0
void
ARMul_InitSymTable ()
{
long i, j, digit;
ENTRY newentry, *oldentry;
SYM_FUNC *symp;
asymbol *symptr;
int key;
bfd *appl_bfd;
bfd *abfd;
long appl_storage_needed;
abfd = bfd_openr ("./vmlinux", 0);
/* <tktan> BUG200105221946 : get symbol from usrappl */
appl_bfd = bfd_openr ("init/usrappl", 0);
if (appl_bfd == NULL)
{
printf ("Can't open init/usrappl\n");
exit (0);
}
if (!bfd_check_format (appl_bfd, bfd_object))
{
printf ("Wrong format\n");
exit (0);
}
appl_storage_needed = bfd_get_symtab_upper_bound (appl_bfd);
if (appl_storage_needed < 0)
{
printf ("FAIL\n");
exit (0);
}
/* <tktan> BUG200105221946 */
if (!bfd_check_format (abfd, bfd_object))
{
printf ("Wrong format\n");
exit (0);
}
storage_needed = bfd_get_symtab_upper_bound (abfd);
if (storage_needed < 0)
{
printf ("FAIL\n");
exit (0);
}
// <tktan> BUG200105221946 :symbol_table = (asymbol **) malloc (storage_needed);
symbol_table = (asymbol **) malloc (appl_storage_needed + storage_needed);
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
kernel_number = number_of_symbols; /* <tktan> BUG200106022219 */
if (number_of_symbols < 0)
{
printf ("FAIL\n");
exit (0);
}
/* <tktan> BUG200105221946 */
number_of_symbols +=
bfd_canonicalize_symtab (appl_bfd, &(symbol_table[number_of_symbols]));
// printf("Number of symbols = %d\n", number_of_symbols) ;
if (!hcreate (number_of_symbols << 1))
{
printf ("Not enough memory for hash table\n");
exit (0);
}
for (i = 0; i < number_of_symbols; i++)
{
symptr = symbol_table[i];
key = symptr->value + symptr->section->vma; // adjust for section address
if (((i < kernel_number) && (symbol_table[i]->flags == 0x01)) || // <tktan> BUG200105172154, BUG200106022219
((i < kernel_number) && (symbol_table[i]->flags == 0x02)) || // <tktan> BUG200204051654
(symbol_table[i]->flags & 0x10))
{ // Is a function symbol
// printf("%x %8x %s\n", symbol_table[i]->flags, key, symbol_table[i]->name);
// ***********************************************************
// This is converting the function symbol value to char string
// and use it as a key in the GNU hash table
// ********************************************************
newentry.key = (char *) malloc (9);
for (j = 0; j < 8; j++)
{
newentry.key[j] = itoa_tab[((key) >> (j << 2)) & 0xf];
}
newentry.key[8] = 0;
// *************************************************
// This is allocating memory for a struct funcsym
// *************************************************
symp = (SYM_FUNC *) malloc (sizeof (SYM_FUNC));
newentry.data = (char *) symp;
symp->name = (char *) symbol_table[i]->name;
symp->total_cycle = 0;
symp->total_energy = 0;
symp->instances = 0;
// ***********************************************
// Insert into hash table
// *******************************************
/* <tktan> BUG200106022219 */
oldentry = hsearch (newentry, FIND);
if (oldentry)
{ // was entered
// printf("Duplicate Symbol: %x %s\n", key, symp->name);
oldentry->data = (char *) symp;
}
else if (!hsearch (newentry, ENTER))
{
printf ("Insufficient memory\n");
exit (0);
}
}
}
return;
}
#else
/**************************************************************************
This function read the symbol list and store into a table
It then generates a hash table based on the value of function symbol
and the data is the pointer to struct funcsym defined in armsym.h
The GNU hash table is used.
**************************************************************************/
/***************
* added by ksh
***************/
void
ARMul_InitSymTable (char *filename)
{
long i, j, digit;
ENTRY newentry, *oldentry;
SYM_FUNC *symp;
asymbol *symptr;
int key;
bfd *abfd;
printf ("call ARMul_InitSymTable,kernle filename is %s. \n", filename);
if (!filename)
{
printf
("Can not get correct kernel filename!Maybe your skyeye.conf have something wrong!\n");
exit (-1);
}
/* <tktan> BUG200105221946 : get symbol from usrappl */
abfd = bfd_openr (filename, 0);
/* <tktan> BUG200105221946 : get symbol from usrappl */
/* <tktan> BUG200105221946 */
if (!bfd_check_format (abfd, bfd_object))
{
printf ("Wrong format\n");
exit (0);
}
storage_needed = bfd_get_symtab_upper_bound (abfd);
if (storage_needed < 0)
{
printf ("FAIL\n");
exit (0);
}
// <tktan> BUG200105221946 :symbol_table = (asymbol **) malloc (storage_needed);
symbol_table = (asymbol **) malloc (storage_needed);
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
kernel_number = number_of_symbols; /* <tktan> BUG200106022219 */
if (number_of_symbols < 0)
{
printf ("FAIL\n");
exit (0);
}
if (!hcreate (number_of_symbols << 1))
{
printf ("Not enough memory for hash table\n");
exit (0);
}
for (i = 0; i < number_of_symbols; i++)
{
symptr = symbol_table[i];
key = symptr->value + symptr->section->vma; // adjust for section address
if (((i < kernel_number) && (symbol_table[i]->flags == 0x01)) || // <tktan> BUG200105172154, BUG200106022219
((i < kernel_number) && (symbol_table[i]->flags == 0x02)) || // <tktan> BUG200204051654
(symbol_table[i]->flags & 0x10))
{ // Is a function symbol
// printf("%x %8x %s\n", symbol_table[i]->flags, key, symbol_table[i]->name);
// ***********************************************************
// This is converting the function symbol value to char string
// and use it as a key in the GNU hash table
// ********************************************************
newentry.key = (char *) malloc (9);
for (j = 0; j < 8; j++)
{
newentry.key[j] = itoa_tab[((key) >> (j << 2)) & 0xf];
}
newentry.key[8] = 0;
// *************************************************
// This is allocating memory for a struct funcsym
// *************************************************
symp = (SYM_FUNC *) malloc (sizeof (SYM_FUNC));
newentry.data = (char *) symp;
symp->name = (char *) symbol_table[i]->name;
symp->total_cycle = 0;
symp->total_energy = 0;
symp->instances = 0;
// ***********************************************
// Insert into hash table
// *******************************************
/* <tktan> BUG200106022219 */
oldentry = hsearch (newentry, FIND);
if (oldentry)
{ // was entered
// printf("Duplicate Symbol: %x %s\n", key, symp->name);
oldentry->data = (char *) symp;
}
else if (!hsearch (newentry, ENTER))
{
printf ("Insufficient memory\n");
exit (0);
}
}
}
return;
}
#endif
/***************************************************************
This function get check the hash table for an entry
If it exists, the corresponding pointer to the SYM_FUNC will
be returned
*************************************************************/
SYM_FUNC *
ARMul_GetSym (ARMword address)
{
int j;
ENTRY entry, *ep;
char text[9];
SYM_FUNC *symp;
//printf("GetSym %x\n", address);
entry.key = text;
for (j = 0; j < 8; j++)
{
entry.key[j] = itoa_tab[(address >> (j << 2)) & 0xf];
}
entry.key[8] = 0;
/*a bug need to fixed */
ep = hsearch (entry, FIND);
if (ep != 0)
{
symp = (SYM_FUNC *) ep->data;
return (symp);
}
else
return (0);
}
/***************************************
* Function to initialize the energy profiling tree root
***************************************************/
void
ARMul_ProfInit (ARMul_State * state) /* <tktan> BUG200103311736 */
{
TASK_STACK *tsp;
printf ("call ARMul_ProfInit \n");
tsp = malloc (sizeof (TASK_STACK));
if (tsp <= 0)
{
printf ("Memory allocation error in ARMul_ProfInit \n");
exit (-1);
}
state->energy.cur_task = (void *) tsp;
tsp->task_id = 0xc00f0000; // where the INIT_TASK reside
memcpy (&(tsp->func_stack[0]), &init_node, sizeof (FUNC_NODE));
tsp->level = 0;
tsp->total_energy = 0;
tsp->total_cycle = 0;
tsp->next = tsp;
return;
}
/****************************************
* Function to create child function node
****************************************/
FUNC_NODE *
ARMul_CreateChild (ARMul_State * state)
{
TASK_STACK *tsp;
int level;
FUNC_NODE *fnp;
tsp = (TASK_STACK *) state->energy.cur_task;
(tsp->level)++;
level = tsp->level;
/* <tktan> BUG200105311233 */
if (level >= MAX_LEVEL)
{
printf ("ARMul_CreateChild failed\n");
assert (0);
}
fnp = &(tsp->func_stack[level]);
// printf("Create Child!\n ");
fnp->tenergy = tsp->total_energy;
fnp->tcycle = tsp->total_cycle;
return (fnp);
}
/******************************************
* Function to destroy child nodes
*****************************************/
void
ARMul_DestroyChild (ARMul_State * state)
{
TASK_STACK *tsp;
int level;
long long fenergy;
long long fcycle;
FUNC_NODE *fnp;
tsp = (TASK_STACK *) state->energy.cur_task;
level = tsp->level;
fnp = &(tsp->func_stack[level]);
// <tktan> BUG200105222137 fenergy = state->t_energy - fnp->tenergy;
fenergy = tsp->total_energy - fnp->tenergy;
fcycle = tsp->total_cycle - fnp->tcycle;
/* <tktan> BUG200105181702 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -