Skip to content
Snippets Groups Projects
Commit c1c1ec36 authored by Avi Kivity's avatar Avi Kivity
Browse files

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.
parent 3527e270
No related branches found
No related tags found
No related merge requests found
...@@ -560,6 +560,9 @@ namespace elf { ...@@ -560,6 +560,9 @@ namespace elf {
void program::set_object(std::string name, elf_object* obj) void program::set_object(std::string name, elf_object* obj)
{ {
_files[name] = 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) elf_object* program::add_object(std::string name)
...@@ -572,6 +575,7 @@ namespace elf { ...@@ -572,6 +575,7 @@ namespace elf {
auto ef = new elf_file(*this, f, name); auto ef = new elf_file(*this, f, name);
ef->set_base(_next_alloc); ef->set_base(_next_alloc);
_files[name] = ef; _files[name] = ef;
_modules.push_back(ef);
ef->load_segments(); ef->load_segments();
_next_alloc = ef->end(); _next_alloc = ef->end();
add_debugger_obj(ef); add_debugger_obj(ef);
...@@ -589,6 +593,7 @@ namespace elf { ...@@ -589,6 +593,7 @@ namespace elf {
auto ef = _files[name]; auto ef = _files[name];
_files.erase(name); _files.erase(name);
_modules.erase(std::find(_modules.begin(), _modules.end(), ef));
ef->unload_segments(); ef->unload_segments();
delete ef; delete ef;
} }
...@@ -606,10 +611,9 @@ namespace elf { ...@@ -606,10 +611,9 @@ namespace elf {
symbol_module program::lookup(const char* name) symbol_module program::lookup(const char* name)
{ {
// FIXME: correct lookup order? for (auto module : _modules) {
for (auto name_module : _files) { if (auto sym = module->lookup_symbol(name)) {
if (auto sym = name_module.second->lookup_symbol(name)) { return symbol_module(sym, module);
return symbol_module(sym, name_module.second);
} }
} }
return symbol_module(nullptr, nullptr); return symbol_module(nullptr, nullptr);
...@@ -630,10 +634,7 @@ namespace elf { ...@@ -630,10 +634,7 @@ namespace elf {
void program::with_modules(std::function<void (std::vector<elf_object*>&)> f) void program::with_modules(std::function<void (std::vector<elf_object*>&)> f)
{ {
// FIXME: locking? // FIXME: locking?
std::vector<elf_object*> tmp; std::vector<elf_object*> tmp = _modules;
for (auto& name_module : _files) {
tmp.push_back(name_module.second);
}
f(tmp); f(tmp);
} }
......
...@@ -342,6 +342,7 @@ namespace elf { ...@@ -342,6 +342,7 @@ namespace elf {
void* _next_alloc; void* _next_alloc;
std::unique_ptr<elf_object> _core; std::unique_ptr<elf_object> _core;
std::map<std::string, elf_object*> _files; std::map<std::string, elf_object*> _files;
std::vector<elf_object*> _modules; // in priority order
// debugger interface // debugger interface
static elf_object* s_objs[100]; static elf_object* s_objs[100];
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment