aboutsummaryrefslogtreecommitdiff
path: root/src/common/module.cc
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org>2015-02-03 23:13:04 +0000
committerthestig@chromium.org <thestig@chromium.org>2015-02-03 23:13:04 +0000
commit89947e7d86eb1ab6e0deeeb5ee0c29ab1a0d1c7a (patch)
tree0722d1ce25e0aabb5bc696c1c73843ffb6529fbe /src/common/module.cc
parentFollow debug link correctly (diff)
downloadbreakpad-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
Diffstat (limited to 'src/common/module.cc')
-rw-r--r--src/common/module.cc21
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)) {