Skip to content

Commit

Permalink
elf: Fix statically-linked executable base address
Browse files Browse the repository at this point in the history
Signed-off-by: Pekka Enberg <[email protected]>
  • Loading branch information
Pekka Enberg committed Nov 18, 2014
1 parent fa19f90 commit 642158a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
25 changes: 23 additions & 2 deletions core/elf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ void* object::entry_point() const {
return nullptr;
}

bool object::is_dynamic() const
{
return _ehdr.e_type == ET_DYN;
}

file::file(program& prog, ::fileref f, std::string pathname)
: object(prog, pathname)
, _f(f)
Expand Down Expand Up @@ -280,6 +285,15 @@ void object::set_base(void* base)
_end = _base + q->p_vaddr + q->p_memsz;
}

Elf64_Addr object::base_addr() const
{
auto p = std::min_element(_phdrs.begin(), _phdrs.end(),
[](Elf64_Phdr a, Elf64_Phdr b)
{ return a.p_type == PT_LOAD
&& a.p_vaddr < b.p_vaddr; });
return p->p_vaddr;
}

void* object::base() const
{
return _base;
Expand Down Expand Up @@ -1040,7 +1054,12 @@ program::load_object(std::string name, std::vector<std::string> extra_path,
trace_elf_load(name.c_str());
auto ef = std::shared_ptr<object>(new file(*this, f, name),
[=](object *obj) { remove_object(obj); });
ef->set_base(_next_alloc);
if (ef->is_dynamic()) {
ef->set_base(_next_alloc);
} else {
auto base = ef->base_addr();
ef->set_base(reinterpret_cast<void*>(base));
}
ef->setprivate(true);
// We need to push the object at the end of the list (so that the main
// shared object gets searched before the shared libraries it uses),
Expand All @@ -1055,7 +1074,9 @@ program::load_object(std::string name, std::vector<std::string> extra_path,
_modules_rcu.assign(new_modules.release());
osv::rcu_dispose(old_modules);
ef->load_segments();
_next_alloc = ef->end();
if (ef->is_dynamic()) {
_next_alloc = ef->end();
}
add_debugger_obj(ef.get());
loaded_objects.push_back(ef);
ef->load_needed(loaded_objects);
Expand Down
2 changes: 2 additions & 0 deletions include/osv/elf.hh
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ public:
void unload_needed();
void relocate();
void set_base(void* base);
Elf64_Addr base_addr() const;
void set_dynamic_table(Elf64_Dyn* dynamic_table);
void* base() const;
void* end() const;
Expand All @@ -335,6 +336,7 @@ public:
std::vector<Elf64_Sym> symbols();
const char * symbol_name(const Elf64_Sym *);
void* entry_point() const;
bool is_dynamic() const;
protected:
virtual void load_segment(const Elf64_Phdr& segment) = 0;
virtual void unload_segment(const Elf64_Phdr& segment) = 0;
Expand Down

0 comments on commit 642158a

Please sign in to comment.