Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 53 additions & 26 deletions src/analyzer/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ app_module_id module_add_or_find(const string &path, module_add_or_find_role rol
for (auto &m: modules) {
id++;
bool approx_match = false;
for (const auto p: m.paths) {
for (const auto &p: m.paths) {
if (p != path) {
size_t p_filename = path_filename_part(p);
approx_match = approx_match || std::equal(
Expand Down Expand Up @@ -316,6 +316,8 @@ void inputEvent(const string &filename, ifstream &fp, vector<Perf_result> &perf,
const uint64_t mmap_offset = offset;
const app_module_id id(module_add_or_find(path, module_add_or_find_role::sample));
const app_module &mod = module_lookup(id);
if (mod.disassemble_error)
throw *mod.disassemble_error;
// find a program header line that this mapping covers entirely.
auto offs = mod.file_offset_to_vaddr.upper_bound(mmap_offset);
if (offs != mod.file_offset_to_vaddr.begin()) offs--;
Expand Down Expand Up @@ -365,7 +367,10 @@ void inputEvent(const string &filename, ifstream &fp, vector<Perf_result> &perf,
id = m.id;
sample_address -= m.addr;
sample_address += m.offset;
module_lookup(id).have_sample = true;
auto &mod = module_lookup(id);
mod.have_sample = true;
if (mod.disassemble_error)
throw *mod.disassemble_error;
break;
}
}
Expand Down Expand Up @@ -755,6 +760,7 @@ void read_disassembly(string filename, objdump_table& objdump_result){
app_module_id current_module(-1);
enum class parser_state {
none,
recovery,
in_file,
in_symbol_table,
in_symbol_table_dynamic,
Expand All @@ -778,6 +784,8 @@ void read_disassembly(string filename, objdump_table& objdump_result){
current_symtab = &empty_symtab;
state = parser_state::in_file;
continue;
} else if (state == parser_state::recovery) {
continue;
} else if (asm_line.substr(0, 15) == "Program Header:") {
state = parser_state::in_program_header;
continue;
Expand All @@ -798,28 +806,44 @@ void read_disassembly(string filename, objdump_table& objdump_result){
continue;
}

switch (state) {
case parser_state::none: break;
case parser_state::in_file: break;
case parser_state::in_program_header:
parse_program_header_line(
filename, lineno, asm_line, current_module,
ph_last_load, ph_off, ph_vaddr
);
break;
case parser_state::in_disassembly:
parse_disassembly_line(
filename, lineno, asm_line, objdump_result, current_module,
*current_symtab, inlined_func_name, source
);
break;
case parser_state::in_symbol_table:
case parser_state::in_symbol_table_dynamic:
parse_symbol_line(
filename, lineno, asm_line, current_module, symbol_table,
state == parser_state::in_symbol_table_dynamic
);
break;
try {
switch (state) {
case parser_state::none: break;
case parser_state::recovery: break;
case parser_state::in_file: break;
case parser_state::in_program_header:
parse_program_header_line(
filename, lineno, asm_line, current_module,
ph_last_load, ph_off, ph_vaddr
);
break;
case parser_state::in_disassembly:
parse_disassembly_line(
filename, lineno, asm_line, objdump_result, current_module,
*current_symtab, inlined_func_name, source
);
break;
case parser_state::in_symbol_table:
case parser_state::in_symbol_table_dynamic:
parse_symbol_line(
filename, lineno, asm_line, current_module, symbol_table,
state == parser_state::in_symbol_table_dynamic
);
break;
}
} catch (parse_error &pe) {
if (current_module != app_module_id(-1)) {
const auto first_instr = objdump_result.lower_bound(address(current_module, 0));
const auto past_last_instr = objdump_result.lower_bound(address(current_module+1, 0));
if (first_instr != past_last_instr)
objdump_result.erase(first_instr, past_last_instr);

auto &mod = module_lookup(current_module);
mod.disassemble_error.reset(new parse_error(std::move(pe)));
mod.have_disassemble = false;
}
state = parser_state::recovery;
current_module = app_module_id(-1);
}
} // end while
asm_code.close();
Expand Down Expand Up @@ -911,7 +935,7 @@ void read_cfg(
x86_64,
aarch64,
} arch = arch::none;
cfg_node *current_node;
cfg_node *current_node = nullptr;
map<app_module_id, string> module_paths;
bool entry_found(false);
unsigned int last_instruction_end = 0;
Expand Down Expand Up @@ -1005,8 +1029,11 @@ void read_cfg(
app_module_id index = m.first;
const string &path = m.second;

module_map[index] = module_add_or_find(path,
app_module_id analyzer_index = module_add_or_find(path,
module_add_or_find_role::count);
module_map[index] = analyzer_index;
if (module_lookup(analyzer_index).disassemble_error)
throw *module_lookup(analyzer_index).disassemble_error;
}

// convert from cfg file module numbering to this session's numbering
Expand Down
6 changes: 6 additions & 0 deletions src/analyzer/support.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@

using namespace std;

class parse_error;

struct app_module {
set<string> paths;
map<uint64_t, pair<uint64_t, uint64_t>> file_offset_to_vaddr;
bool have_disassemble = false;
bool have_count = false;
bool have_sample = false;
std::unique_ptr<parse_error> disassemble_error = nullptr;
uint64_t samples = 0;
uint64_t counts = 0;

Expand Down Expand Up @@ -165,4 +168,7 @@ typedef map<address, shared_ptr<function>> func_table;
typedef map<address, sample_point> func_sample;
typedef map<address, cfg_node> dycfg;

/* for parse_error */
#include "io.hpp"

#endif