📄 armsym.c
字号:
if ((state->energy.enable_func_energy)
&& !(strcmp (state->energy.func_energy, fnp->func_symbol->name)))
{
printf ("energy_report %s %f\n", fnp->func_symbol->name, fenergy);
}
/* <tktan> BUG200104101936 */
if (state->energy.energy_prof)
{
fnp->func_symbol->total_energy += fenergy;
fnp->func_symbol->total_cycle += fcycle;
(fnp->func_symbol->instances)++;
}
//printf("Destroy child,name %s \n",fnp->func_symbol->name);
tsp->level = level - 1;
return;
}
/************************************************
Function to check the different kind of branch
************************************************/
void
ARMul_CallCheck (ARMul_State * state, ARMword cur_pc, ARMword to_pc,
ARMword instr)
{
FUNC_NODE *child_node;
TASK_STACK *tsp;
SYM_FUNC *symp;
int i, bt, level;
ARMword new_task_id, fp_value;
tsp = (TASK_STACK *) state->energy.cur_task;
level = tsp->level;
fp_value = state->Reg[11]; // BUG200311301153
#if 0
if (debug != tsp->task_id || !debug)
{
printf ("cur_task is changed! %x \n", tsp->task_id);
debug = tsp->task_id;
}
#endif
/* <tktan> BUG200105311233 */
if (level >= MAX_LEVEL)
{
printf ("ARMul_CallCheck failed\n");
printf ("level %d \n", level);
//exit(-1);
}
// First check if it is normal return
if (to_pc == (tsp->func_stack[level].ret_addr + 4))
{
if (state->energy.func_display & state->energy.func_disp_start)
{ /* <tktan> BUG200104191428 */
//if(1){
printf ("[%x:%d:%x] Function return %s (%x)--> %s (%x)\n",
tsp->task_id, level, fp_value,
tsp->func_stack[level].func_symbol->name, cur_pc,
tsp->func_stack[level - 1].func_symbol->name, to_pc);
}
/* <tktan> BUG200104101736 */
ARMul_DestroyChild (state);
return;
}
// Check if it is a trap return
// a trap return is one that jump to a saved interrupted address, saved
// in .ret_addr
bt = 0;
while ((level - bt >= 0) && (bt <= 3))
{
if (to_pc == tsp->func_stack[level - bt].ret_addr)
{
if (state->energy.func_display & state->energy.func_disp_start)
{ /* <tktan> BUG200104191428 */
printf ("[%x:%d:%x] Trap Return -> %s\n", tsp->task_id, level,
fp_value,
tsp->func_stack[level - bt - 1].func_symbol->name);
}
/* <tktan> BUG200104101736 */
for (i = 0; i <= bt; i++)
{
ARMul_DestroyChild (state);
}
return;
}
bt++;
}
// BUG200311212039
// check if it is a recursive call, or I was missing some returns through
// abnormal jumps
bt = 0;
while ((level - bt >= 0) && (bt <= 2))
{
if (to_pc == tsp->func_stack[level - bt].func_start_addr)
{
if (state->energy.func_display & state->energy.func_disp_start)
{ /* <tktan> BUG200104191428 */
printf ("[%x:%d:%x] Function %s ended\n", tsp->task_id, level,
fp_value,
tsp->func_stack[level - bt].func_symbol->name);
}
/* <tktan> BUG200104101736 */
for (i = 0; i <= bt; i++)
{
ARMul_DestroyChild (state);
}
}
bt++;
}
tsp = (TASK_STACK *) state->energy.cur_task;
level = tsp->level;
// check if it is a trap
//if (!(to_pc & 0xffffffe0) && (state->Reg[14] == (cur_pc+4))) { // check for pc from 0x0 - 0x1f
// BUG200311302126: Reg[14]_abt is cur_pc+8 for DataAbort,
// but cur_pc+4 for other exception. So, better not check it
if (!(to_pc & 0xffffffe0))
{ // check for pc from 0x0 - 0x1f
child_node = ARMul_CreateChild (state); /* <tktan> BUG200104101736 */
child_node->ret_addr = cur_pc;
child_node->func_start_addr = to_pc;
child_node->func_symbol = &trap_sym;
if (state->energy.func_display & state->energy.func_disp_start)
{ /* <tktan> BUG200104191428 */
printf ("[%x:%d:%x] Function %s(%x) --> Trap %x\n", tsp->task_id,
level, fp_value, tsp->func_stack[level].func_symbol->name,
cur_pc, to_pc);
}
return;
}
// Check if it is a function call
if ((state->Reg[14] == (cur_pc + 4)) || /* <tktan> BUG200105172030 */
(BITS (20, 27) & 0xf0) == 0xb0)
{ /* <tktan> BUG200104012116 */
symp = ARMul_GetSym (to_pc);
if (symp)
{
// it is an entry into a function
child_node = ARMul_CreateChild (state); /* <tktan> BUG2001040101736 */
child_node->ret_addr = cur_pc;
child_node->func_start_addr = to_pc;
child_node->func_symbol = symp;
/* <tktan> BUG200105211055 : perform task switch */
if (!strcmp (symp->name, "__switch_to"))
{ // BUG200204021340
ARMul_TaskSwitch (state);
}
if (!strcmp (symp->name, "copy_thread"))
{
new_task_id = ARMul_TaskCreate (state);
}
}
} /* <tktan> BUG200104012116 */
// Just a normal branch, maybe
return;
}
/* <tktan> BUG200105211055 : perform task switch */
void
ARMul_TaskSwitch (ARMul_State * state)
{
TASK_STACK *ctsp, *oldtsp, *newtsp;
//ARMword to_thread_id;
ARMword to_task_id;
int done = 0;
//to_thread_id = state->Reg[2] ; // r1, the to_task task structure
to_task_id = state->Reg[7];
oldtsp = (TASK_STACK *) state->energy.cur_task;
//printf("cur_task id %x \n",state->Reg[0]);
oldtsp->task_id = state->Reg[0]; /* <tktan> BUG200106051701 */
//printf("Task ThreadInfo Switch from %x to %x\n", oldtsp->thread_id, to_thread_id);
//printf("task switch from %x to %x \n",oldtsp->task_id,to_task_id);
ctsp = oldtsp->next;
while (!done && (ctsp != oldtsp))
{
if (ctsp->task_id == to_task_id)
{
done = 1;
newtsp = ctsp;
}
// printf("ctsp taskid=%x,next task_id=%x \n",ctsp->task_id,ctsp->next->task_id);
ctsp = ctsp->next;
}
if (done)
state->energy.cur_task = (void *) newtsp;
else
{
printf ("Error : Can not find task stack\n");
//print_allTask(state);
exit (-1);
}
}
void
print_allTask (ARMul_State * state)
{
TASK_STACK *ctsp, *oldtsp, *newtsp;
ARMword to_task_id;
oldtsp = (TASK_STACK *) state->energy.cur_task;
ctsp = oldtsp;
#if 0
printf ("Begin to print all task...\n");
do
{
printf ("ctsp taskid=%x,next task_id=%x \n", ctsp->task_id,
ctsp->next->task_id);
ctsp = ctsp->next;
}
while (ctsp != oldtsp);
printf ("End to print....\n");
#endif
}
/* <tktan> BUG200105211055 : create new task stack */
ARMword
ARMul_TaskCreate (ARMul_State * state)
{
TASK_STACK *oldtsp, *newtsp, *oldnext;
ARMword to_task_id;
int i;
to_task_id = state->Reg[3]; // r3, the to_task task structure
if (to_task_id == 0x00000000)
{ // BUG200204081717
to_task_id = state->Reg[5]; // r5 store the to_task task structure
}
oldtsp = (TASK_STACK *) state->energy.cur_task;
newtsp = malloc (sizeof (TASK_STACK));
memcpy (newtsp, oldtsp, sizeof (TASK_STACK));
newtsp->task_id = to_task_id;
newtsp->level -= 2; // point to the SWI level
/* <tktan> BUG200105222137 */
newtsp->total_cycle = 0;
// newtsp->total_energy = 0.0; BUG200106142205, possible problem
newtsp->total_energy = 0;
for (i = 0; i <= newtsp->level; i++)
{
newtsp->func_stack[i].tcycle = 0;
newtsp->func_stack[i].tenergy = 0;
}
/* put newtsp after oldtsp */
oldnext = oldtsp->next;
oldtsp->next = newtsp;
newtsp->next = oldnext;
//printf("Create a new task,task_id=%x \n",to_task_id);
//print_allTask(state);
return (to_task_id);
}
/********************************************
* Function to report energy tree
*******************************************/
void
ARMul_ReportEnergy (ARMul_State * state, FILE * pf)
{
int i, j;
ENTRY entry, *ep;
char text[9];
SYM_FUNC *symp;
asymbol *symptr;
ARMword address;
TASK_STACK *ctsp, *oldtsp;
float energy;
ARMul_Consolidate (state); // <tktan> BUG200105222137
for (i = 0; i < number_of_symbols; i++)
{
symptr = symbol_table[i];
address = 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, BUG200311211406
(symbol_table[i]->flags & 0x10))
{ // Is a function symbol
// ***********************************************************
// This is converting the function symbol value to char string
// and use it as a key in the GNU hash table
// ********************************************************
entry.key = text;
for (j = 0; j < 8; j++)
{
entry.key[j] = itoa_tab[(address >> (j << 2)) & 0xf];
}
entry.key[8] = 0;
ep = hsearch (entry, FIND);
if (ep != 0)
{
symp = (SYM_FUNC *) ep->data;
/*modified by ksh for evaluate the usrappl program only */
/*
if(strncmp(symp->name,"usrappl",7) != 0){
continue;
}
*/
if (symp->instances > 0)
{ // only show if executed
energy = symp->total_energy;
fprintf (pf, "%s %d %lld %f\n", symp->name, symp->instances,
symp->total_cycle, energy);
}
}
}
}
/* <tktan> BUG200105222137 : print out task energy */
oldtsp = (TASK_STACK *) state->energy.cur_task;
ctsp = oldtsp;
do
{
energy = ctsp->total_energy;
fprintf (pf, "Task[%x] %lld %f\n", ctsp->task_id, ctsp->total_cycle,
energy);
ctsp = ctsp->next;
}
while (ctsp != oldtsp);
}
/* <tktan> BUG200105222137 : consolidate unfinished function energy */
void
ARMul_Consolidate (ARMul_State * state)
{
long long fenergy; // <tktan> BUG200106142205
long long fcycle; // <tktan> BUG200106142205
FUNC_NODE *fnp;
TASK_STACK *ctsp, *oldtsp;
int i;
double energy;
/* <tktan> BUG200105222137 : report energy for tasks */
/* <tktan> BUG200106041235 : use do instead of while */
oldtsp = (TASK_STACK *) state->energy.cur_task;
ctsp = oldtsp;
do
{
for (i = ctsp->level; i >= 0; i--)
{
fnp = &(ctsp->func_stack[i]);
fenergy = ctsp->total_energy - fnp->tenergy;
fcycle = ctsp->total_cycle - fnp->tcycle;
/* copied from <tktan> BUG200105181702 */
if ((state->energy.enable_func_energy)
&&
!(strcmp (state->energy.func_energy, fnp->func_symbol->name)))
{
//energy = I2ENERGY(fenergy);
//fprintf(pf,"energy_report %s %f\n", fnp->func_symbol->name, energy);
}
/* copied from <tktan> BUG200104101936 */
fnp->func_symbol->total_energy += fenergy;
fnp->func_symbol->total_cycle += fcycle;
(fnp->func_symbol->instances)++;
}
ctsp = ctsp->next;
}
while (ctsp != oldtsp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -