diff options
Diffstat (limited to '3rdParty/Breakpad/src/common/module.cc')
-rw-r--r-- | 3rdParty/Breakpad/src/common/module.cc | 125 |
1 files changed, 78 insertions, 47 deletions
diff --git a/3rdParty/Breakpad/src/common/module.cc b/3rdParty/Breakpad/src/common/module.cc index 4e257d1..b5fcb62 100644 --- a/3rdParty/Breakpad/src/common/module.cc +++ b/3rdParty/Breakpad/src/common/module.cc @@ -49,11 +49,13 @@ using std::hex; Module::Module(const string &name, const string &os, - const string &architecture, const string &id) : + const string &architecture, const string &id, + const string &code_id /* = "" */) : name_(name), os_(os), architecture_(architecture), id_(id), + code_id_(code_id), load_address_(0) { } Module::~Module() { @@ -79,8 +81,34 @@ void Module::AddFunction(Function *function) { // FUNC lines must not hold an empty name, so catch the problem early if // callers try to add one. assert(!function->name.empty()); + + // FUNCs are better than PUBLICs as they come with sizes, so remove an extern + // with the same address if present. + Extern ext(function->address); + ExternSet::iterator it_ext = externs_.find(&ext); + if (it_ext == externs_.end() && + architecture_ == "arm" && + (function->address & 0x1) == 0) { + // ARM THUMB functions have bit 0 set. ARM64 does not have THUMB. + Extern arm_thumb_ext(function->address | 0x1); + it_ext = externs_.find(&arm_thumb_ext); + } + if (it_ext != externs_.end()) { + delete *it_ext; + externs_.erase(it_ext); + } +#if _DEBUG + { + // There should be no other PUBLIC symbols that overlap with the function. + Extern debug_ext(function->address); + ExternSet::iterator it_debug = externs_.lower_bound(&ext); + assert(it_debug == externs_.end() || + (*it_debug)->address >= function->address + function->size); + } +#endif + std::pair<FunctionSet::iterator,bool> ret = functions_.insert(function); - if (!ret.second) { + if (!ret.second && (*ret.first != function)) { // Free the duplicate that was not inserted because this Module // now owns it. delete function; @@ -130,8 +158,7 @@ Module::File *Module::FindFile(const string &name) { FileByNameMap::iterator destiny = files_.lower_bound(&name); if (destiny == files_.end() || *destiny->first != name) { // Repeated string comparison, boo hoo. - File *file = new File; - file->name = name; + File *file = new File(name); file->source_id = -1; destiny = files_.insert(destiny, FileByNameMap::value_type(&file->name, file)); @@ -155,7 +182,7 @@ void Module::GetFiles(vector<File *> *vec) { vec->push_back(it->second); } -void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) { +void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) const { *vec = stack_frame_entries_; } @@ -204,62 +231,66 @@ bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) { return stream.good(); } -bool Module::Write(std::ostream &stream, bool cfi) { +bool Module::Write(std::ostream &stream, SymbolData symbol_data) { stream << "MODULE " << os_ << " " << architecture_ << " " << id_ << " " << name_ << endl; if (!stream.good()) return ReportError(); - AssignSourceIds(); + if (!code_id_.empty()) { + stream << "INFO CODE_ID " << code_id_ << endl; + } - // Write out files. - for (FileByNameMap::iterator file_it = files_.begin(); - file_it != files_.end(); ++file_it) { - File *file = file_it->second; - if (file->source_id >= 0) { - stream << "FILE " << file->source_id << " " << file->name << endl; - if (!stream.good()) - return ReportError(); + if (symbol_data != ONLY_CFI) { + AssignSourceIds(); + + // Write out files. + for (FileByNameMap::iterator file_it = files_.begin(); + file_it != files_.end(); ++file_it) { + File *file = file_it->second; + if (file->source_id >= 0) { + stream << "FILE " << file->source_id << " " << file->name << endl; + if (!stream.good()) + return ReportError(); + } } - } - // Write out functions and their lines. - for (FunctionSet::const_iterator func_it = functions_.begin(); - func_it != functions_.end(); ++func_it) { - Function *func = *func_it; - stream << "FUNC " << hex - << (func->address - load_address_) << " " - << func->size << " " - << func->parameter_size << " " - << func->name << dec << endl; - - if (!stream.good()) - return ReportError(); - for (vector<Line>::iterator line_it = func->lines.begin(); - line_it != func->lines.end(); ++line_it) { - stream << hex - << (line_it->address - load_address_) << " " - << line_it->size << " " - << dec - << line_it->number << " " - << line_it->file->source_id << endl; + // Write out functions and their lines. + for (FunctionSet::const_iterator func_it = functions_.begin(); + func_it != functions_.end(); ++func_it) { + Function *func = *func_it; + stream << "FUNC " << hex + << (func->address - load_address_) << " " + << func->size << " " + << func->parameter_size << " " + << func->name << dec << endl; if (!stream.good()) return ReportError(); + + for (vector<Line>::iterator line_it = func->lines.begin(); + line_it != func->lines.end(); ++line_it) { + stream << hex + << (line_it->address - load_address_) << " " + << line_it->size << " " + << dec + << line_it->number << " " + << line_it->file->source_id << endl; + if (!stream.good()) + return ReportError(); + } } - } - // Write out 'PUBLIC' records. - for (ExternSet::const_iterator extern_it = externs_.begin(); - extern_it != externs_.end(); ++extern_it) { - Extern *ext = *extern_it; - stream << "PUBLIC " << hex - << (ext->address - load_address_) << " 0 " - << ext->name << dec << endl; - if (!stream.good()) - return ReportError(); + // Write out 'PUBLIC' records. + for (ExternSet::const_iterator extern_it = externs_.begin(); + extern_it != externs_.end(); ++extern_it) { + Extern *ext = *extern_it; + stream << "PUBLIC " << hex + << (ext->address - load_address_) << " 0 " + << ext->name << dec << endl; + } } - if (cfi) { + if (symbol_data != NO_CFI) { // Write out 'STACK CFI INIT' and 'STACK CFI' records. vector<StackFrameEntry *>::const_iterator frame_it; for (frame_it = stack_frame_entries_.begin(); |