1 |
2 |
mballance |
/*
|
2 |
|
|
* fwrisc_ctest_base.cpp
|
3 |
|
|
*
|
4 |
|
|
* Created on: Nov 19, 2018
|
5 |
|
|
* Author: ballance
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
#include "fwrisc_ctest_base.h"
|
9 |
|
|
#include "GoogletestVlCmdlineProcessor.h"
|
10 |
|
|
#include <stdio.h>
|
11 |
|
|
|
12 |
|
|
fwrisc_ctest_base::fwrisc_ctest_base(uint32_t timeout) : fwrisc_instr_tests(timeout) {
|
13 |
|
|
// TODO Auto-generated constructor stub
|
14 |
|
|
|
15 |
|
|
}
|
16 |
|
|
|
17 |
|
|
fwrisc_ctest_base::~fwrisc_ctest_base() {
|
18 |
|
|
// TODO Auto-generated destructor stub
|
19 |
|
|
}
|
20 |
|
|
|
21 |
|
|
void fwrisc_ctest_base::SetUp() {
|
22 |
|
|
const GoogletestVlCmdlineProcessor &clp = GoogletestVlCmdlineProcessor::instance();
|
23 |
|
|
std::string elf_file, v;
|
24 |
|
|
fwrisc_instr_tests::SetUp();
|
25 |
|
|
|
26 |
|
|
m_trace_funcs = clp.has_plusarg("+TRACE_FUNCS");
|
27 |
|
|
m_trace_instr = clp.has_plusarg("+TRACE_INSTR");
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
clp.get_plusarg_value("+SW_IMAGE", elf_file);
|
31 |
|
|
|
32 |
|
|
if (!m_symtab.read(elf_file)) {
|
33 |
|
|
fprintf(stdout, "Error: failed to read elf file\n");
|
34 |
|
|
}
|
35 |
|
|
|
36 |
|
|
// m_ram_console = m_symtab.find_sym("ram_console").st_value;
|
37 |
|
|
// // _Fault is called when the main function returns
|
38 |
|
|
// m_halt_addr = m_symtab.find_sym("_Fault").st_value;
|
39 |
|
|
// fprintf(stdout, "Ram Console: 0x%08x\n", m_ram_console);
|
40 |
|
|
}
|
41 |
|
|
|
42 |
|
|
void fwrisc_ctest_base::exec(uint32_t addr, uint32_t instr) {
|
43 |
|
|
// fprintf(stdout, "exec: 0x%08x\n", addr);
|
44 |
|
|
if (m_trace_funcs) {
|
45 |
|
|
if (m_call_stack.size() == 0) {
|
46 |
|
|
// Look for an entry symbol
|
47 |
|
|
int32_t sym_idx;
|
48 |
|
|
|
49 |
|
|
if ((sym_idx = m_symtab.find_sym(addr)) != -1) {
|
50 |
|
|
if (sym_idx+1 >= m_symtab.n_syms()) {
|
51 |
|
|
fprintf(stdout, "Error: entering the last symbol in the file\n");
|
52 |
|
|
fflush(stdout);
|
53 |
|
|
}
|
54 |
|
|
const Elf32_Sym &next = m_symtab.get_sym(sym_idx+1);
|
55 |
|
|
const std::string &func = m_symtab.get_sym_name(sym_idx);
|
56 |
|
|
if (m_filter_funcs.find(func) == m_filter_funcs.end()) {
|
57 |
|
|
fprintf(stdout, "%s==> %s\n", m_indent.c_str(), func.c_str());
|
58 |
|
|
fflush(stdout);
|
59 |
|
|
}
|
60 |
|
|
m_call_stack.push(std::pair<Elf32_Addr,Elf32_Addr>(addr,next.st_value-4));
|
61 |
|
|
m_indent.append(" ");
|
62 |
|
|
}
|
63 |
|
|
} else {
|
64 |
|
|
// We should be in a function
|
65 |
|
|
const std::pair<Elf32_Addr,Elf32_Addr> &func = m_call_stack.top();
|
66 |
|
|
|
67 |
|
|
if (addr < func.first || addr > func.second) {
|
68 |
|
|
// We're outside the current function
|
69 |
|
|
int32_t sym_idx;
|
70 |
|
|
|
71 |
|
|
if ((sym_idx = m_symtab.find_sym(addr)) != -1) {
|
72 |
|
|
// We jumped to the beginning of a new function
|
73 |
|
|
// Consider this entering a new function
|
74 |
|
|
if (sym_idx+1 >= m_symtab.n_syms()) {
|
75 |
|
|
fprintf(stdout, "Error: entering the last symbol in the file\n");
|
76 |
|
|
fflush(stdout);
|
77 |
|
|
}
|
78 |
|
|
const Elf32_Sym &next = m_symtab.get_sym(sym_idx+1);
|
79 |
|
|
const std::string &func = m_symtab.get_sym_name(sym_idx);
|
80 |
|
|
if (m_filter_funcs.find(func) == m_filter_funcs.end()) {
|
81 |
|
|
fprintf(stdout, "%s==> %s\n", m_indent.c_str(), func.c_str());
|
82 |
|
|
fflush(stdout);
|
83 |
|
|
}
|
84 |
|
|
m_call_stack.push(std::pair<Elf32_Addr,Elf32_Addr>(addr,next.st_value-4));
|
85 |
|
|
m_indent.append(" ");
|
86 |
|
|
} else {
|
87 |
|
|
sym_idx = m_symtab.find_sym(func.first);
|
88 |
|
|
// Consider this exiting the current scope
|
89 |
|
|
m_call_stack.pop();
|
90 |
|
|
|
91 |
|
|
const std::pair<Elf32_Addr,Elf32_Addr> &new_func = m_call_stack.top();
|
92 |
|
|
|
93 |
|
|
m_indent = m_indent.substr(0, m_indent.size()-2);
|
94 |
|
|
if (addr >= new_func.first && addr <= new_func.second) {
|
95 |
|
|
const std::string &func = m_symtab.get_sym_name(sym_idx);
|
96 |
|
|
if (m_filter_funcs.find(func) == m_filter_funcs.end()) {
|
97 |
|
|
fprintf(stdout, "%s<== %s\n", m_indent.c_str(), func.c_str());
|
98 |
|
|
fflush(stdout);
|
99 |
|
|
}
|
100 |
|
|
} else {
|
101 |
|
|
// fprintf(stdout, "Error: left function for unknown scope 0x%08x..0x%08x (0x%08x)\n",
|
102 |
|
|
// new_func.first, new_func.second, addr);
|
103 |
|
|
// fflush(stdout);
|
104 |
|
|
}
|
105 |
|
|
}
|
106 |
|
|
}
|
107 |
|
|
}
|
108 |
|
|
}
|
109 |
|
|
|
110 |
|
|
// std::string sym;
|
111 |
|
|
// if (m_trace_funcs) {
|
112 |
|
|
// if (m_symtab.find_sym(addr, sym)) {
|
113 |
|
|
// fprintf(stdout, "EXEC: %s (0x%08x)\n", sym.c_str(), addr);
|
114 |
|
|
// }
|
115 |
|
|
// }
|
116 |
|
|
if (m_trace_instr) {
|
117 |
|
|
fprintf(stdout, "EXEC: 0x%08x\n", addr);
|
118 |
|
|
}
|
119 |
|
|
|
120 |
|
|
if (addr == m_halt_addr) {
|
121 |
|
|
fprintf(stdout, "hit halt address 0x%08x\n", m_halt_addr);
|
122 |
|
|
m_end_of_test = true;
|
123 |
|
|
dropObjection(this);
|
124 |
|
|
}
|
125 |
|
|
}
|
126 |
|
|
|