diff options
author | thestig@chromium.org <thestig@chromium.org> | 2015-02-03 23:13:04 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org> | 2015-02-03 23:13:04 +0000 |
commit | 89947e7d86eb1ab6e0deeeb5ee0c29ab1a0d1c7a (patch) | |
tree | 0722d1ce25e0aabb5bc696c1c73843ffb6529fbe | |
parent | Follow debug link correctly (diff) | |
download | breakpad-89947e7d86eb1ab6e0deeeb5ee0c29ab1a0d1c7a.tar.xz |
Handle ARM THUMB functions when removing duplicate PUBLIC entries.
In ELF symtab/dynsym sections, THUMB function addresses have bit 0 set,
whereas the DWARF function entries are not.
R=mark@chromium.org
Review URL: https://breakpad.appspot.com/7774002
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1423 4c0a9323-5329-0410-9bdc-e9ce6186880e
-rw-r--r-- | src/common/module.cc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/common/module.cc b/src/common/module.cc index d880ce57..fa798f48 100644 --- a/src/common/module.cc +++ b/src/common/module.cc @@ -83,12 +83,27 @@ void Module::AddFunction(Function *function) { // 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_.lower_bound(&ext); - if (it_ext != externs_.end() && - (*it_ext)->address < function->address + function->size) { + 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 && (*ret.first != function)) { |