summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Breakpad/src/common/module.cc')
-rw-r--r--3rdParty/Breakpad/src/common/module.cc125
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();