DwarfReader: fixed linetable mapping
This change alters/corrects DwarfReader's way of determining the size of linetable entries (i.e. their "range size"); the interface (e.g. to ElfReader) stays the same. Prior to this, it was assumed that static instructions within "the linetable" were sorted in ascending order. This assumption turned out to be false, as every compilation unit's header has its own linetable and the compilation unit headers are not sorted by their static instructions. Furthermore this change implements normalization of file names. Change-Id: Ia4beb7bf9cfb6f1a499aeebd01228335b70ab52d
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
#include <limits>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
#include "DwarfReader.hpp"
|
||||
#include "libdwarf.h"
|
||||
@ -180,6 +181,10 @@ bool DwarfReader::read_source_files(const std::string& fileName,std::list<std::s
|
||||
}
|
||||
|
||||
bool DwarfReader::read_mapping(std::string fileName, std::list<DwarfLineMapping>& lineMapping) {
|
||||
// temporary mapping of instruction address to (file, line)
|
||||
// => static instruction addresses are sorted ascendingly for the whole binary
|
||||
// (i.e. all instructions from all CUs!)
|
||||
std::map<unsigned, SourceLine> instr_to_sourceline;
|
||||
|
||||
// Open The file
|
||||
int fd=open(fileName.c_str(),O_RDONLY);
|
||||
@ -237,21 +242,10 @@ bool DwarfReader::read_mapping(std::string fileName, std::list<DwarfLineMapping>
|
||||
}
|
||||
|
||||
if (lineNo&&isCode) {
|
||||
/* default the linetable's address range (->size) to the maximum
|
||||
* possible range. this results in the last linetable entry having
|
||||
* maximum range. as this always (?) is a function epilogue, its
|
||||
* irrelevant for our use-case. */
|
||||
// TODO: properly determine the last interval's range, e.g. via __TEXT_END
|
||||
|
||||
DwarfLineMapping mapping(addr, (std::numeric_limits<unsigned>::max() - addr),
|
||||
lineNo, lineSource);
|
||||
// the address range for the previous line ends with the current line's address
|
||||
if (!lineMapping.empty()) {
|
||||
DwarfLineMapping& back = lineMapping.back();
|
||||
// update the previous lineRangeSize appropriately
|
||||
back.line_range_size = (addr - back.absolute_addr);
|
||||
}
|
||||
lineMapping.push_back(mapping);
|
||||
// wrap line_number and source_file into an object
|
||||
SourceLine tmp_sl(normalize(lineSource), lineNo);
|
||||
// store SourceLine object with static instr in the map
|
||||
instr_to_sourceline.insert(std::make_pair(addr, tmp_sl));
|
||||
}
|
||||
|
||||
dwarf_dealloc(dbg,lineSource,DW_DLA_STRING);
|
||||
@ -269,6 +263,26 @@ bool DwarfReader::read_mapping(std::string fileName, std::list<DwarfLineMapping>
|
||||
return false;
|
||||
}
|
||||
|
||||
// iterate instr_to_sourceline to determine the "line_range_size" for mapping
|
||||
std::map<unsigned, SourceLine>::iterator it;
|
||||
for (it = instr_to_sourceline.begin(); it != instr_to_sourceline.end(); it++) {
|
||||
unsigned addr = it->first;
|
||||
SourceLine sl = it->second;
|
||||
|
||||
/* Default the linetable's address range (->"size") to the maximum
|
||||
* possible value. This results in the last linetable entry having
|
||||
* maximum range. This entry will either be a dummy or a function's
|
||||
* epilogue, both of which are irrelevant for our (current) use cases.
|
||||
* All other entries' sizes are set properly. */
|
||||
DwarfLineMapping mapping(addr, (std::numeric_limits<unsigned>::max() - addr),
|
||||
sl.line_number, sl.source_file);
|
||||
if (!lineMapping.empty()) {
|
||||
DwarfLineMapping& back = lineMapping.back();
|
||||
back.line_range_size = addr - back.absolute_addr;
|
||||
}
|
||||
lineMapping.push_back(mapping);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7,6 +7,16 @@
|
||||
|
||||
namespace fail {
|
||||
|
||||
// temporary wrapper object for (file, linenumber)
|
||||
class SourceLine {
|
||||
public:
|
||||
std::string source_file;
|
||||
unsigned line_number;
|
||||
|
||||
SourceLine(std::string source, unsigned line) : source_file(source), line_number(line) {}
|
||||
};
|
||||
|
||||
// wrapper object for insertion into DB
|
||||
class DwarfLineMapping {
|
||||
public:
|
||||
unsigned absolute_addr;
|
||||
|
||||
Reference in New Issue
Block a user