import-trace: ElfImporter cleanups
- added several insert_multiple() flushes (which completely broke
the import before)
- import_source_code() refactored
- parameter naming improved
- better error handling
- whitespace/coding-style cleanups
- documentation added + cleanups
Change-Id: I70ac95391b9678e0dcce8adfa7df69a4f91ca30d
This commit is contained in:
@ -21,17 +21,19 @@ static Logger LOG("ElfImporter");
|
|||||||
* Callback function that can be used to add command line options
|
* Callback function that can be used to add command line options
|
||||||
* to the campaign
|
* to the campaign
|
||||||
*/
|
*/
|
||||||
bool ElfImporter::cb_commandline_init() {
|
bool ElfImporter::cb_commandline_init()
|
||||||
|
{
|
||||||
CommandLine &cmd = CommandLine::Inst();
|
CommandLine &cmd = CommandLine::Inst();
|
||||||
|
|
||||||
OBJDUMP = cmd.addOption("", "objdump", Arg::Required,
|
OBJDUMP = cmd.addOption("", "objdump", Arg::Required,
|
||||||
"--objdump \tObjdump: location of objdump binary, otherwise LLVM Disassembler is used");
|
"--objdump \tObjdump: location of objdump binary, otherwise LLVM Disassembler is used");
|
||||||
SOURCECODE = cmd.addOption("", "sources", Arg::None,
|
SOURCECODE = cmd.addOption("", "sources", Arg::None,
|
||||||
"--sources \timport all source files and the mapping of code line<->static instruction into the database");
|
"--sources \timport all source files and the mapping of code line<->static instruction into the database");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::create_database() {
|
bool ElfImporter::create_database()
|
||||||
|
{
|
||||||
CommandLine &cmd = CommandLine::Inst();
|
CommandLine &cmd = CommandLine::Inst();
|
||||||
std::stringstream create_statement;
|
std::stringstream create_statement;
|
||||||
|
|
||||||
@ -88,7 +90,8 @@ bool ElfImporter::create_database() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::copy_to_database(ProtoIStream &ps) {
|
bool ElfImporter::copy_to_database(ProtoIStream &ps)
|
||||||
|
{
|
||||||
if (!m_elf) {
|
if (!m_elf) {
|
||||||
LOG << "please give an elf binary as parameter (-e/--elf)" << std::endl;
|
LOG << "please give an elf binary as parameter (-e/--elf)" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
@ -101,7 +104,7 @@ bool ElfImporter::copy_to_database(ProtoIStream &ps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd[OBJDUMP]) { // using objdump
|
if (cmd[OBJDUMP]) { // using objdump
|
||||||
if(!import_with_objdump(std::string(cmd[OBJDUMP].first()->arg))) {
|
if (!import_with_objdump(std::string(cmd[OBJDUMP].first()->arg))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -111,19 +114,19 @@ bool ElfImporter::copy_to_database(ProtoIStream &ps) {
|
|||||||
if (cmd[SOURCECODE]) { // import sources
|
if (cmd[SOURCECODE]) { // import sources
|
||||||
std::list<std::string> sourceFiles;
|
std::list<std::string> sourceFiles;
|
||||||
|
|
||||||
if (!import_source_files(m_elf->getFilename(),sourceFiles)) {
|
if (!import_source_files(m_elf->getFilename(), sourceFiles)) {
|
||||||
cerr << "unable to read dwarf2 debug info" << endl;
|
cerr << "unable to read dwarf2 debug info" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::list<std::string>::iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) {
|
for (std::list<std::string>::iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) {
|
||||||
if(!import_source_code(*it)) {
|
if (!import_source_code(*it)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// import debug information
|
// import debug information
|
||||||
if(!import_mapping(m_elf->getFilename())) {
|
if (!import_mapping(m_elf->getFilename())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +134,8 @@ bool ElfImporter::copy_to_database(ProtoIStream &ps) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::import_with_objdump(const std::string &binary) {
|
bool ElfImporter::import_with_objdump(const std::string &binary)
|
||||||
|
{
|
||||||
#ifndef __puma
|
#ifndef __puma
|
||||||
|
|
||||||
LOG << "importing with " << binary << std::endl;
|
LOG << "importing with " << binary << std::endl;
|
||||||
@ -162,7 +166,8 @@ bool ElfImporter::import_with_objdump(const std::string &binary) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::evaluate_objdump_line(const std::string& line){
|
bool ElfImporter::evaluate_objdump_line(const std::string& line)
|
||||||
|
{
|
||||||
#ifndef __puma
|
#ifndef __puma
|
||||||
// Only read in real code lines:
|
// Only read in real code lines:
|
||||||
// Code lines start with a leading whitespace! (hopefully in each objdump implementation!)
|
// Code lines start with a leading whitespace! (hopefully in each objdump implementation!)
|
||||||
@ -198,7 +203,7 @@ bool ElfImporter::evaluate_objdump_line(const std::string& line){
|
|||||||
|
|
||||||
/* import instruction into database */
|
/* import instruction into database */
|
||||||
if (!import_instruction(addr, opcode_read, opcode_length,
|
if (!import_instruction(addr, opcode_read, opcode_length,
|
||||||
instruction, comment))
|
instruction, comment))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +214,8 @@ bool ElfImporter::evaluate_objdump_line(const std::string& line){
|
|||||||
|
|
||||||
|
|
||||||
bool ElfImporter::import_instruction(fail::address_t addr, char *opcode, int opcode_length,
|
bool ElfImporter::import_instruction(fail::address_t addr, char *opcode, int opcode_length,
|
||||||
const std::string &instruction, const std::string &comment) {
|
const std::string &instruction, const std::string &comment)
|
||||||
|
{
|
||||||
/* Prepare a mysql statement if it was not done before */
|
/* Prepare a mysql statement if it was not done before */
|
||||||
static MYSQL_STMT *stmt = 0;
|
static MYSQL_STMT *stmt = 0;
|
||||||
if (!stmt) {
|
if (!stmt) {
|
||||||
@ -263,163 +269,172 @@ bool ElfImporter::import_instruction(fail::address_t addr, char *opcode, int opc
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::import_source_code(std::string fileName) {
|
static inline std::string rtrim(std::string str)
|
||||||
|
{
|
||||||
|
std::string whitespaces(" \t\f\v\n\r");
|
||||||
|
|
||||||
|
std::size_t found = str.find_last_not_of(whitespaces);
|
||||||
|
if (found != std::string::npos) {
|
||||||
|
str.erase(found+1);
|
||||||
|
} else {
|
||||||
|
str.clear();
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ElfImporter::import_source_code(std::string fileName)
|
||||||
|
{
|
||||||
LOG << "Importing Sourcefile: " << fileName << endl;
|
LOG << "Importing Sourcefile: " << fileName << endl;
|
||||||
|
|
||||||
ifstream in(fileName.c_str());
|
ifstream in(fileName.c_str());
|
||||||
if (!in.is_open()) {
|
if (!in.is_open()) {
|
||||||
LOG << "Sourcefile not found: " << fileName << endl;
|
LOG << "Sourcefile not found: " << fileName << endl;
|
||||||
} else {
|
return true; // we can live with this
|
||||||
unsigned lineNo=0;
|
|
||||||
while (!in.eof()) {
|
|
||||||
++lineNo;
|
|
||||||
|
|
||||||
// Read and strip the current line
|
|
||||||
string currentLine;
|
|
||||||
getline(in,currentLine);
|
|
||||||
if ((!currentLine.length())&&(in.eof())) break;
|
|
||||||
while (true) {
|
|
||||||
unsigned l=currentLine.length();
|
|
||||||
if (!l) break;
|
|
||||||
char c=currentLine[l-1];
|
|
||||||
if ((c!='\n')&&(c!='\r')&&(c!=' ')&&(c!='\t')) break;
|
|
||||||
currentLine=currentLine.substr(0,l-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Sonderzeichen
|
|
||||||
currentLine = db->escape_string(currentLine);
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "SELECT file_id FROM dbg_filename "
|
|
||||||
<< "WHERE path = '" << fileName.c_str() << "' "
|
|
||||||
<< "AND variant_id = " << m_variant_id;
|
|
||||||
|
|
||||||
MYSQL_RES *res = db->query(ss.str().c_str(), true);
|
|
||||||
MYSQL_ROW row;
|
|
||||||
row = mysql_fetch_row(res);
|
|
||||||
|
|
||||||
// INSERT group entry
|
|
||||||
std::stringstream sql;
|
|
||||||
|
|
||||||
sql << "(" << m_variant_id << "," << lineNo << ",";
|
|
||||||
if (row != NULL) {
|
|
||||||
sql << row[0];
|
|
||||||
} else {
|
|
||||||
sql << -1;
|
|
||||||
}
|
|
||||||
sql << "," << "\"" << currentLine << "\"" << ")";
|
|
||||||
|
|
||||||
if (!db->insert_multiple("INSERT INTO dbg_source (variant_id, linenumber, file_id, line) VALUES ", sql.str().c_str())){
|
|
||||||
LOG << "Can not import sourcelines!" << endl;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
db->insert_multiple();
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ElfImporter::import_source_files(const std::string& fileName,std::list<std::string>& lines) {
|
// retrieve file_id
|
||||||
|
std::stringstream ss;
|
||||||
//std::list<addrToLine> lines;
|
ss << "SELECT file_id FROM dbg_filename "
|
||||||
if (!dwReader.read_source_files(fileName, lines)) {
|
<< "WHERE path = '" << fileName.c_str() << "' "
|
||||||
|
<< "AND variant_id = " << m_variant_id;
|
||||||
|
MYSQL_RES *res = db->query(ss.str().c_str(), true);
|
||||||
|
if (!res) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (std::list<std::string>::iterator it = lines.begin(); it != lines.end(); ++it) {
|
MYSQL_ROW row;
|
||||||
// INSERT group entry
|
if (!(row = mysql_fetch_row(res))) {
|
||||||
std::stringstream sql;
|
// this should not happen
|
||||||
sql << "(" << m_variant_id << "," << "\"" << (*it).c_str() << "\"" << ")";
|
LOG << "error: no entry for '" << fileName.c_str() << "' in dbg_filename, aborting" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string file_id = row[0];
|
||||||
|
|
||||||
if(!db->insert_multiple("INSERT INTO dbg_filename (variant_id, path) VALUES ", sql.str().c_str())){
|
// import lines from this file
|
||||||
LOG << "Can not import filename!"<< endl;
|
for (unsigned lineNo = 1; !in.eof(); ++lineNo) {
|
||||||
|
// read and strip a line
|
||||||
|
string currentLine;
|
||||||
|
getline(in, currentLine);
|
||||||
|
if (!currentLine.length() && in.eof()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentLine = rtrim(currentLine);
|
||||||
|
|
||||||
|
// escape special characters for use in SQL
|
||||||
|
currentLine = db->escape_string(currentLine);
|
||||||
|
|
||||||
|
// insert line into dbg_source
|
||||||
|
std::stringstream sql;
|
||||||
|
sql << "(" << m_variant_id << "," << lineNo
|
||||||
|
<< "," << file_id << ",'" << currentLine << "')";
|
||||||
|
if (!db->insert_multiple("INSERT INTO dbg_source (variant_id, linenumber, file_id, line) VALUES ",
|
||||||
|
sql.str().c_str())) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
db->insert_multiple();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::import_mapping(std::string fileName) {
|
bool ElfImporter::import_source_files(const std::string& elf_filename, std::list<std::string>& filenames)
|
||||||
|
{
|
||||||
|
if (!dwReader.read_source_files(elf_filename, filenames)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (std::list<std::string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
|
||||||
|
// INSERT group entry
|
||||||
|
std::stringstream sql;
|
||||||
|
sql << "(" << m_variant_id << ",'" << it->c_str() << "')";
|
||||||
|
|
||||||
|
if (!db->insert_multiple("INSERT INTO dbg_filename (variant_id, path) VALUES ",
|
||||||
|
sql.str().c_str())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db->insert_multiple();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ElfImporter::import_mapping(std::string fileName)
|
||||||
|
{
|
||||||
std::list<addrToLine> mapping;
|
std::list<addrToLine> mapping;
|
||||||
if (!dwReader.read_mapping(fileName, mapping)) {
|
if (!dwReader.read_mapping(fileName, mapping)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!mapping.empty())
|
while (!mapping.empty()) {
|
||||||
{
|
|
||||||
struct addrToLine temp_addrToLine;
|
struct addrToLine temp_addrToLine;
|
||||||
temp_addrToLine = mapping.front();
|
temp_addrToLine = mapping.front();
|
||||||
|
|
||||||
|
// FIXME reuse file_id from previous iteration if file name stays constant
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "SELECT file_id FROM dbg_filename "
|
ss << "SELECT file_id FROM dbg_filename "
|
||||||
<< "WHERE path = '" << temp_addrToLine.lineSource << "' "
|
<< "WHERE path = '" << temp_addrToLine.lineSource << "' "
|
||||||
<< "AND variant_id = " << m_variant_id;
|
<< "AND variant_id = " << m_variant_id;
|
||||||
|
|
||||||
MYSQL_RES *res = db->query(ss.str().c_str(), true);
|
MYSQL_RES *res = db->query(ss.str().c_str(), true);
|
||||||
|
if (!res) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
row = mysql_fetch_row(res);
|
row = mysql_fetch_row(res);
|
||||||
|
|
||||||
// INSERT group entry
|
// INSERT group entry
|
||||||
std::stringstream sql;
|
std::stringstream sql;
|
||||||
sql << "(" << m_variant_id << "," << temp_addrToLine.absoluteAddr << "," << temp_addrToLine.lineNumber << ",";
|
sql << "(" << m_variant_id << "," << temp_addrToLine.absoluteAddr << "," << temp_addrToLine.lineNumber << ",";
|
||||||
if(row != NULL) {
|
if (row != NULL) {
|
||||||
sql << row[0] << ")";
|
sql << row[0] << ")";
|
||||||
} else {
|
} else {
|
||||||
sql << -1 << ")";
|
// this should not happen
|
||||||
|
LOG << "error: no entry for '" << temp_addrToLine.lineSource << "' in dbg_filename, aborting" << std::endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//ToDo: Skip duplicated entrys with ON DUPLICATE KEY UPDATE
|
// TODO: Skip duplicated entries with ON DUPLICATE KEY UPDATE (?)
|
||||||
if(!db->insert_multiple("INSERT IGNORE INTO dbg_mapping (variant_id, instr_absolute, linenumber, file_id) VALUES ", sql.str().c_str())){
|
if (!db->insert_multiple("INSERT IGNORE INTO dbg_mapping (variant_id, instr_absolute, linenumber, file_id) VALUES ",
|
||||||
LOG << "Can not import line number information!" << endl;;
|
sql.str().c_str())) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping.pop_front();
|
mapping.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db->insert_multiple();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElfImporter::clear_database() {
|
bool ElfImporter::clear_database()
|
||||||
|
{
|
||||||
CommandLine &cmd = CommandLine::Inst();
|
CommandLine &cmd = CommandLine::Inst();
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
bool ret = true;
|
bool ret = true, result;
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "DELETE FROM objdump WHERE variant_id = " << m_variant_id;
|
ss << "DELETE FROM objdump WHERE variant_id = " << m_variant_id;
|
||||||
|
result = db->query(ss.str().c_str());
|
||||||
if (ret) {
|
ret = ret && result;
|
||||||
ret = db->query(ss.str().c_str()) == 0 ? false : true;
|
|
||||||
}
|
|
||||||
LOG << "deleted " << db->affected_rows() << " rows from objdump table" << std::endl;
|
LOG << "deleted " << db->affected_rows() << " rows from objdump table" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
//ToDo: Reset auto increment value to 1
|
|
||||||
if (cmd[SOURCECODE]) {
|
if (cmd[SOURCECODE]) {
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "DELETE FROM dbg_source WHERE variant_id = " << m_variant_id;
|
ss << "DELETE FROM dbg_source WHERE variant_id = " << m_variant_id;
|
||||||
|
result = db->query(ss.str().c_str());
|
||||||
if (ret) {
|
ret = ret && result;
|
||||||
ret = db->query(ss.str().c_str()) == 0 ? false : true;
|
|
||||||
}
|
|
||||||
LOG << "deleted " << db->affected_rows() << " rows from dbg_source table" << std::endl;
|
LOG << "deleted " << db->affected_rows() << " rows from dbg_source table" << std::endl;
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "DELETE FROM dbg_filename WHERE variant_id = " << m_variant_id;
|
ss << "DELETE FROM dbg_filename WHERE variant_id = " << m_variant_id;
|
||||||
|
result = db->query(ss.str().c_str());
|
||||||
if (ret) {
|
ret = ret && result;
|
||||||
ret = db->query(ss.str().c_str()) == 0 ? false : true;
|
LOG << "deleted " << db->affected_rows() << " rows from dbg_filename table" << std::endl;
|
||||||
}
|
|
||||||
LOG << "deleted " << db->affected_rows() << " rows from dbg_source table" << std::endl;
|
|
||||||
|
|
||||||
//ToDo: Reset auto increment value to 1
|
//ToDo: Reset auto increment value to 1
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "DELETE FROM dbg_mapping WHERE variant_id = " << m_variant_id;
|
ss << "DELETE FROM dbg_mapping WHERE variant_id = " << m_variant_id;
|
||||||
|
result = db->query(ss.str().c_str());
|
||||||
if (ret) {
|
ret = ret && result;
|
||||||
ret = db->query(ss.str().c_str()) == 0 ? false : true;
|
|
||||||
}
|
|
||||||
LOG << "deleted " << db->affected_rows() << " rows from source table" << std::endl;
|
LOG << "deleted " << db->affected_rows() << " rows from source table" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,21 +14,18 @@
|
|||||||
/**
|
/**
|
||||||
The ElfImporter is not a real trace importer, but we locate it
|
The ElfImporter is not a real trace importer, but we locate it
|
||||||
into the import-trace utility, since here the infrastructure is
|
into the import-trace utility, since here the infrastructure is
|
||||||
already in place to import things related to an elf binary into
|
already in place to import things related to an ELF binary into
|
||||||
the database.
|
the database.
|
||||||
|
|
||||||
The ElfImporter calls objdump and dissassembles an elf binary
|
The ElfImporter calls objdump and dissassembles an ELF binary
|
||||||
and imports the results into the database
|
and imports the results into the database
|
||||||
|
|
||||||
In addition, debugging information can be imported:
|
In addition, debugging information can be imported:
|
||||||
|
|
||||||
If the --sources option is set, the source files will be imported
|
If the --sources option is set, the source files will be imported
|
||||||
into the database. Only the files that were actually used in the
|
into the database. Only the files that were actually used in the
|
||||||
elf binary will be imported.
|
ELF binary will be imported. Additionally, the line number table of the
|
||||||
|
ELF binary will be imported into the database.
|
||||||
If the --debug option is set, the line number table of the elf binary will
|
|
||||||
be imported into the database. The information will be stored in the
|
|
||||||
"mapping" table.
|
|
||||||
*/
|
*/
|
||||||
class ElfImporter : public Importer {
|
class ElfImporter : public Importer {
|
||||||
llvm::OwningPtr<llvm::object::Binary> binary;
|
llvm::OwningPtr<llvm::object::Binary> binary;
|
||||||
@ -44,24 +41,24 @@ class ElfImporter : public Importer {
|
|||||||
|
|
||||||
/* Imports a single instruction into the objdump table */
|
/* Imports a single instruction into the objdump table */
|
||||||
bool import_instruction(fail::address_t addr, char opcode[16], int opcode_length,
|
bool import_instruction(fail::address_t addr, char opcode[16], int opcode_length,
|
||||||
const std::string &instruction, const std::string &comment);
|
const std::string &instruction, const std::string &comment);
|
||||||
|
|
||||||
bool import_source_files(const std::string& fileName,std::list<std::string>& lines);
|
bool import_source_files(const std::string& elf_filename, std::list<std::string>& filenames);
|
||||||
bool import_source_code(std::string fileName);
|
bool import_source_code(std::string fileName);
|
||||||
bool import_mapping(std::string fileName);
|
bool import_mapping(std::string fileName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
|
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
|
||||||
Trace_Event &ev) { return true; }
|
Trace_Event &ev) { return true; }
|
||||||
virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr,
|
virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr,
|
||||||
Trace_Event &ev) { return true; }
|
Trace_Event &ev) { return true; }
|
||||||
|
|
||||||
virtual void open_unused_ec_intervals() {
|
virtual void open_unused_ec_intervals() {
|
||||||
/* empty, Memory Map has a no meaning in this importer */
|
/* empty, Memory Map has a no meaning in this importer */
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ElfImporter() : Importer() {};
|
ElfImporter() : Importer() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function that can be used to add command line options
|
* Callback function that can be used to add command line options
|
||||||
|
|||||||
Reference in New Issue
Block a user