Hi,

Could you please run 'readelf -W -l ' against this executable? Maybe it is 
a statically linked executable.

It is determined by this expression:

bool is_statically_linked() { return !_is_dynamically_linked_executable && 
_ehdr.e_entry; }

and _is_dynamically_linked_executable is set to true if there is PT_INTERP 
header.

On Sunday, September 10, 2023 at 5:24:43 AM UTC-4 n...@scylladb.com wrote:

> When I try to run the default scripts/build (the Lua shell) on Fedora 38 
> (with https://github.com/cloudius-systems/osv/pull/1257),
> I get the error message added in this patch:
>
> $ scripts/run.py 
> OSv v0.57.0-61-g72ed41c6
> eth0: 192.168.122.15
> Booted up in 156.82 ms
> Cmdline: /cli
>
> Statically linked executables are not supported yet!
>
> Why does it think the Lua executable is statically linked?
>
> --
> Nadav Har'El
> n...@scylladb.com
>
>
> On Thu, Aug 31, 2023 at 9:51 AM Commit Bot <b...@cloudius-systems.com> 
> wrote:
>
>> From: Nadav Har'El <n...@scylladb.com>
>> Committer: Nadav Har'El <n...@scylladb.com>
>> Branch: master
>>
>> Merge 'Dynamic linker: support loading and processing statically linked 
>> executables' from WALDEMAR KOZACZUK
>>
>> The two commits provide necessary modifications to the OSv dynamic linker 
>> to support loading and processing statically linked executables.
>>
>> Please note these changes are NOT enough to make OSv run statically 
>> linked executables.
>>
>> Closes #1253
>>
>> * github.com:cloudius-systems/osv:
>>   dynamic linker: support loading and processing static ELF
>>   dynamic linker: rename is_executable to is_dynamically_linked_executable
>>
>> ---
>> diff --git a/arch/aarch64/arch-elf.cc b/arch/aarch64/arch-elf.cc
>> --- a/arch/aarch64/arch-elf.cc
>> +++ b/arch/aarch64/arch-elf.cc
>> @@ -66,7 +66,7 @@ bool object::arch_relocate_rela(u32 type, u32 sym, void 
>> *addr,
>>          if (sym) {
>>              auto sm = symbol(sym);
>>              ulong tls_offset;
>> -            if (sm.obj->is_executable()) {
>> +            if (sm.obj->is_dynamically_linked_executable()) {
>>                  // If this is an executable (pie or position-dependant 
>> one)
>>                  // then the variable is located in the reserved slot of 
>> the TLS
>>                  // right where the kernel TLS lives
>> @@ -119,7 +119,7 @@ void object::arch_relocate_tls_desc(u32 sym, void 
>> *addr, Elf64_Sxword addend)
>>      ulong tls_offset;
>>      if (sym) {
>>          auto sm = symbol(sym);
>> -        if (sm.obj->is_executable() || sm.obj->is_core()) {
>> +        if (sm.obj->is_dynamically_linked_executable() || 
>> sm.obj->is_core()) {
>>              // If this is an executable (pie or position-dependant one)
>>              // then the variable is located in the reserved slot of the 
>> TLS
>>              // right where the kernel TLS lives
>> @@ -163,7 +163,7 @@ void object::prepare_initial_tls(void* buffer, size_t 
>> size,
>>
>>  void object::prepare_local_tls(std::vector<ptrdiff_t>& offsets)
>>  {
>> -    if (!_static_tls && !is_executable()) {
>> +    if (!_static_tls && !is_dynamically_linked_executable()) {
>>          return;
>>      }
>>
>> diff --git a/arch/aarch64/arch-switch.hh b/arch/aarch64/arch-switch.hh
>> --- a/arch/aarch64/arch-switch.hh
>> +++ b/arch/aarch64/arch-switch.hh
>> @@ -120,7 +120,7 @@ void thread::setup_tcb()
>>          assert(obj);
>>          user_tls_size = obj->initial_tls_size();
>>          user_tls_data = obj->initial_tls();
>> -        if (obj->is_executable()) {
>> +        if (obj->is_dynamically_linked_executable()) {
>>             executable_tls_size = obj->get_tls_size();
>>          }
>>      }
>> diff --git a/arch/x64/arch-elf.cc b/arch/x64/arch-elf.cc
>> --- a/arch/x64/arch-elf.cc
>> +++ b/arch/x64/arch-elf.cc
>> @@ -138,7 +138,7 @@ bool object::arch_relocate_rela(u32 type, u32 sym, 
>> void *addr,
>>          if (sym) {
>>              auto sm = symbol(sym);
>>              ulong tls_offset;
>> -            if (sm.obj->is_executable()) {
>> +            if (sm.obj->is_dynamically_linked_executable()) {
>>                  // If this is an executable (pie or position-dependant 
>> one)
>>                  // then the variable is located in the reserved slot of 
>> the TLS
>>                  // right where the kernel TLS lives
>> @@ -202,7 +202,7 @@ void object::prepare_initial_tls(void* buffer, size_t 
>> size,
>>
>>  void object::prepare_local_tls(std::vector<ptrdiff_t>& offsets)
>>  {
>> -    if (!_static_tls && !is_executable()) {
>> +    if (!_static_tls && !is_dynamically_linked_executable()) {
>>          return;
>>      }
>>
>> diff --git a/arch/x64/arch-switch.hh b/arch/x64/arch-switch.hh
>> --- a/arch/x64/arch-switch.hh
>> +++ b/arch/x64/arch-switch.hh
>> @@ -210,7 +210,7 @@ void thread::setup_tcb()
>>          assert(obj);
>>          user_tls_size = obj->initial_tls_size();
>>          user_tls_data = obj->initial_tls();
>> -        if (obj->is_executable()) {
>> +        if (obj->is_dynamically_linked_executable()) {
>>             executable_tls_size = obj->get_tls_size();
>>             aligned_executable_tls_size = obj->get_aligned_tls_size();
>>          }
>> diff --git a/core/elf.cc b/core/elf.cc
>> --- a/core/elf.cc
>> +++ b/core/elf.cc
>> @@ -123,7 +123,7 @@ object::object(program& prog, std::string pathname)
>>      , _initial_tls_size(0)
>>      , _dynamic_table(nullptr)
>>      , _module_index(_prog.register_dtv(this))
>> -    , _is_executable(false)
>> +    , _is_dynamically_linked_executable(false)
>>      , _init_called(false)
>>      , _eh_frame(0)
>>      , _visibility_thread(nullptr)
>> @@ -249,9 +249,6 @@ const char * object::symbol_name(const Elf64_Sym * 
>> sym) {
>>  }
>>
>>  void* object::entry_point() const {
>> -    if (!_is_executable) {
>> -        return nullptr;
>> -    }
>>      return _base + _ehdr.e_entry;
>>  }
>>
>> @@ -366,13 +363,13 @@ void object::set_base(void* base)
>>                                [](const Elf64_Phdr* a, const Elf64_Phdr* 
>> b)
>>                                    { return a->p_vaddr < b->p_vaddr; });
>>
>> -    if (!is_core() && is_non_pie_executable()) {
>> -        // Verify non-PIE executable does not collide with the kernel
>> +    if (!is_core() && !is_pic()) {
>> +        // Verify non-PIC executable ((aka position dependent)) does not 
>> collide with the kernel
>>          if (intersects_with_kernel(p->p_vaddr) || 
>> intersects_with_kernel(q->p_vaddr + q->p_memsz)) {
>> -            abort("Non-PIE executable [%s] collides with kernel: [%p-%p] 
>> !\n",
>> +            abort("Non-PIC executable [%s] collides with kernel: [%p-%p] 
>> !\n",
>>                      pathname().c_str(), p->p_vaddr, q->p_vaddr + 
>> q->p_memsz);
>>          }
>> -        // Override the passed in value as the base for non-PIEs 
>> (Position Dependant Executables)
>> +        // Override the passed in value as the base for non-PICs 
>> (Position Dependant Executables)
>>          // needs to be set to 0 because all the addresses in it are 
>> absolute
>>          _base = 0x0;
>>      } else {
>> @@ -484,7 +481,7 @@ void object::process_headers()
>>              _dynamic_table = reinterpret_cast<Elf64_Dyn*>(_base + 
>> phdr.p_vaddr);
>>              break;
>>          case PT_INTERP:
>> -            _is_executable = true;
>> +            _is_dynamically_linked_executable = true;
>>              break;
>>          case PT_NOTE: {
>>              if (phdr.p_memsz < 16) {
>> @@ -536,10 +533,10 @@ void object::process_headers()
>>              abort("Unknown p_type in executable %s: %d\n", pathname(), 
>> phdr.p_type);
>>          }
>>      }
>> -    if (!is_core() && _ehdr.e_type == ET_EXEC && !_is_executable) {
>> -        abort("Statically linked executables are not supported!\n");
>> +    if (!is_core() && is_statically_linked()) {
>> +        abort("Statically linked executables are not supported yet!\n");
>>      }
>> -    if (_is_executable && _tls_segment) {
>> +    if (_is_dynamically_linked_executable && _tls_segment) {
>>          auto app_tls_size = get_aligned_tls_size();
>>          ulong pie_static_tls_maximum_size = &_pie_static_tls_end - 
>> &_pie_static_tls_start;
>>          if (app_tls_size > pie_static_tls_maximum_size) {
>> @@ -600,6 +597,12 @@ void object::fix_permissions()
>>          make_text_writable(false);
>>      }
>>
>> +    //Full RELRO applies to dynamically linked executables only
>> +    if (is_statically_linked()) {
>> +        return;
>> +    }
>> +
>> +    //Process GNU_RELRO segments only to make GOT and others read-only
>>      for (auto&& phdr : _phdrs) {
>>          if (phdr.p_type != PT_GNU_RELRO)
>>              continue;
>> @@ -888,6 +891,9 @@ constexpr Elf64_Versym old_version_symbol_mask = 
>> Elf64_Versym(1) << 15;
>>
>>  Elf64_Sym* object::lookup_symbol_old(const char* name)
>>  {
>> +    if (!dynamic_exists(DT_SYMTAB)) {
>> +        return nullptr;
>> +    }
>>      auto symtab = dynamic_ptr<Elf64_Sym>(DT_SYMTAB);
>>      auto strtab = dynamic_ptr<char>(DT_STRTAB);
>>      auto hashtab = dynamic_ptr<Elf64_Word>(DT_HASH);
>> @@ -917,6 +923,9 @@ dl_new_hash(const char *s)
>>
>>  Elf64_Sym* object::lookup_symbol_gnu(const char* name, bool self_lookup)
>>  {
>> +    if (!dynamic_exists(DT_SYMTAB)) {
>> +        return nullptr;
>> +    }
>>      auto symtab = dynamic_ptr<Elf64_Sym>(DT_SYMTAB);
>>      auto strtab = dynamic_ptr<char>(DT_STRTAB);
>>      auto hashtab = dynamic_ptr<Elf64_Word>(DT_GNU_HASH);
>> @@ -1019,6 +1028,9 @@ dladdr_info object::lookup_addr(const void* addr)
>>      if (addr < _base || addr >= _end) {
>>          return ret;
>>      }
>> +    if (!dynamic_exists(DT_STRTAB)) {
>> +        return ret;
>> +    }
>>      ret.fname = _pathname.c_str();
>>      ret.base = _base;
>>      auto strtab = dynamic_ptr<char>(DT_STRTAB);
>> @@ -1068,6 +1080,9 @@ static std::string dirname(std::string path)
>>
>>  void object::load_needed(std::vector<std::shared_ptr<object>>& 
>> loaded_objects)
>>  {
>> +    if (!dynamic_exists(DT_NEEDED)) {
>> +        return;
>> +    }
>>      std::vector<std::string> rpath;
>>
>>      std::string rpath_str;
>> @@ -1263,7 +1278,7 @@ void object::init_static_tls()
>>          if (obj->is_core()) {
>>              continue;
>>          }
>> -        if (obj->is_executable()) {
>> +        if (obj->is_dynamically_linked_executable()) {
>>              obj->prepare_local_tls(_initial_tls_offsets);
>>              elf_debug("Initialized local-exec static TLS for %s\n", 
>> obj->pathname().c_str());
>>          }
>> @@ -1462,7 +1477,7 @@ program::load_object(std::string name, 
>> std::vector<std::string> extra_path,
>>          osv::rcu_dispose(old_modules);
>>          ef->load_segments();
>>          ef->process_headers();
>> -        if (!ef->is_non_pie_executable())
>> +        if (ef->is_pic())
>>             _next_alloc = ef->end();
>>          add_debugger_obj(ef.get());
>>          loaded_objects.push_back(ef);
>> diff --git a/include/osv/elf.hh b/include/osv/elf.hh
>> --- a/include/osv/elf.hh
>> +++ b/include/osv/elf.hh
>> @@ -378,9 +378,9 @@ public:
>>      size_t initial_tls_size() { return _initial_tls_size; }
>>      void* initial_tls() { return _initial_tls.get(); }
>>      void* get_tls_segment() { return _tls_segment; }
>> -    bool is_non_pie_executable() { return _ehdr.e_type == ET_EXEC; }
>> +    bool is_pic() { return _ehdr.e_type != ET_EXEC; }
>>      std::vector<ptrdiff_t>& initial_tls_offsets() { return 
>> _initial_tls_offsets; }
>> -    bool is_executable() { return _is_executable; }
>> +    bool is_dynamically_linked_executable() { return 
>> _is_dynamically_linked_executable; }
>>      ulong get_tls_size();
>>      ulong get_aligned_tls_size();
>>      void copy_local_tls(void* to_addr);
>> @@ -415,6 +415,7 @@ private:
>>      void prepare_local_tls(std::vector<ptrdiff_t>& offsets);
>>      void alloc_static_tls();
>>      void make_text_writable(bool flag);
>> +    bool is_statically_linked() { return 
>> !_is_dynamically_linked_executable && _ehdr.e_entry; }
>>  protected:
>>      program& _prog;
>>      std::string _pathname;
>> @@ -435,7 +436,7 @@ protected:
>>      Elf64_Dyn* _dynamic_table;
>>      ulong _module_index;
>>      std::unique_ptr<char[]> _section_names_cache;
>> -    bool _is_executable;
>> +    bool _is_dynamically_linked_executable;
>>      bool is_core();
>>      bool _init_called;
>>      void* _eh_frame;
>> @@ -462,7 +463,7 @@ protected:
>>      bool arch_relocate_jump_slot(symbol_module& sym, void *addr, 
>> Elf64_Sxword addend);
>>      void arch_relocate_tls_desc(u32 sym, void *addr, Elf64_Sxword 
>> addend);
>>      size_t static_tls_end() {
>> -        if (is_core() || is_executable()) {
>> +        if (is_core() || _is_dynamically_linked_executable) {
>>              return 0;
>>          }
>>          return _static_tls_offset + get_tls_size();
>>
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/8eed9d97-8548-4041-bf48-def7334bcaa4n%40googlegroups.com.

Reply via email to