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
This commit is contained in:
thestig@chromium.org 2015-02-03 23:13:04 +00:00
parent 854b9f74a0
commit 89947e7d86

View file

@ -83,12 +83,27 @@ void Module::AddFunction(Function *function) {
// FUNCs are better than PUBLICs as they come with sizes, so remove an extern // FUNCs are better than PUBLICs as they come with sizes, so remove an extern
// with the same address if present. // with the same address if present.
Extern ext(function->address); Extern ext(function->address);
ExternSet::iterator it_ext = externs_.lower_bound(&ext); ExternSet::iterator it_ext = externs_.find(&ext);
if (it_ext != externs_.end() && if (it_ext == externs_.end() &&
(*it_ext)->address < function->address + function->size) { 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; delete *it_ext;
externs_.erase(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); std::pair<FunctionSet::iterator,bool> ret = functions_.insert(function);
if (!ret.second && (*ret.first != function)) { if (!ret.second && (*ret.first != function)) {