From c1c1ec3690f565cc8d7523431b03cc3a1dbe8d94 Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi@cloudius-systems.com> Date: Sun, 17 Feb 2013 12:49:59 +0200 Subject: [PATCH] elf: fix symbol resolution order to use load order This fixes an issue where a symbol exists in multiple objects; when just one is loaded it is resolved to one of the modules, but after the second is loaded, it resolves to the second. To the program this appears as if the address or contents of a static variable has changed. In our case this was triggered by both statically and dynamically linking a library. --- core/elf.cc | 17 +++++++++-------- include/elf.hh | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/core/elf.cc b/core/elf.cc index eca8d4017..d89954e59 100644 --- a/core/elf.cc +++ b/core/elf.cc @@ -560,6 +560,9 @@ namespace elf { void program::set_object(std::string name, elf_object* obj) { _files[name] = obj; + if (std::find(_modules.begin(), _modules.end(), obj) == _modules.end()) { + _modules.push_back(obj); + } } elf_object* program::add_object(std::string name) @@ -572,6 +575,7 @@ namespace elf { auto ef = new elf_file(*this, f, name); ef->set_base(_next_alloc); _files[name] = ef; + _modules.push_back(ef); ef->load_segments(); _next_alloc = ef->end(); add_debugger_obj(ef); @@ -589,6 +593,7 @@ namespace elf { auto ef = _files[name]; _files.erase(name); + _modules.erase(std::find(_modules.begin(), _modules.end(), ef)); ef->unload_segments(); delete ef; } @@ -606,10 +611,9 @@ namespace elf { symbol_module program::lookup(const char* name) { - // FIXME: correct lookup order? - for (auto name_module : _files) { - if (auto sym = name_module.second->lookup_symbol(name)) { - return symbol_module(sym, name_module.second); + for (auto module : _modules) { + if (auto sym = module->lookup_symbol(name)) { + return symbol_module(sym, module); } } return symbol_module(nullptr, nullptr); @@ -630,10 +634,7 @@ namespace elf { void program::with_modules(std::function<void (std::vector<elf_object*>&)> f) { // FIXME: locking? - std::vector<elf_object*> tmp; - for (auto& name_module : _files) { - tmp.push_back(name_module.second); - } + std::vector<elf_object*> tmp = _modules; f(tmp); } diff --git a/include/elf.hh b/include/elf.hh index 7534ccc10..b973f6a49 100644 --- a/include/elf.hh +++ b/include/elf.hh @@ -342,6 +342,7 @@ namespace elf { void* _next_alloc; std::unique_ptr<elf_object> _core; std::map<std::string, elf_object*> _files; + std::vector<elf_object*> _modules; // in priority order // debugger interface static elf_object* s_objs[100]; }; -- GitLab