elf.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <kernel/errno.h>
  2. #include <kernel/stdio.hpp>
  3. #include <types/assert.h>
  4. #include <types/elf.hpp>
  5. #include <types/stdint.h>
  6. template <typename T>
  7. constexpr void _user_push(uint32_t** sp, T d)
  8. {
  9. *sp -= sizeof(T);
  10. *(T*)*sp = d;
  11. }
  12. int types::elf::elf32_load(types::elf::elf32_load_data* d)
  13. {
  14. auto* ent_exec = fs::vfs_open(d->exec);
  15. if (!ent_exec) {
  16. d->errcode = ENOENT;
  17. return GB_FAILED;
  18. }
  19. // TODO: detect file format
  20. types::elf::elf32_header hdr {};
  21. auto n_read = fs::vfs_read(
  22. ent_exec->ind,
  23. (char*)&hdr,
  24. sizeof(types::elf::elf32_header),
  25. 0, sizeof(types::elf::elf32_header));
  26. if (n_read != sizeof(types::elf::elf32_header)) {
  27. d->errcode = EINVAL;
  28. return GB_FAILED;
  29. }
  30. size_t phents_size = hdr.phentsize * hdr.phnum;
  31. auto* phents = (types::elf::elf32_program_header_entry*)k_malloc(phents_size);
  32. n_read = fs::vfs_read(
  33. ent_exec->ind,
  34. (char*)phents,
  35. phents_size,
  36. hdr.phoff, phents_size);
  37. // broken file or I/O error
  38. if (n_read != phents_size) {
  39. d->errcode = EINVAL;
  40. return GB_FAILED;
  41. }
  42. for (int i = 0; i < hdr.phnum; ++i) {
  43. if (phents->type != types::elf::elf32_program_header_entry::PT_LOAD)
  44. continue;
  45. auto ret = mmap((void*)phents->vaddr, phents->memsz, ent_exec->ind, phents->offset, 1, d->system);
  46. if (ret != GB_OK) {
  47. d->errcode = ret;
  48. return GB_FAILED;
  49. }
  50. ++phents;
  51. }
  52. // map stack area
  53. auto ret = mmap((void*)types::elf::ELF_STACK_TOP, types::elf::ELF_STACK_SIZE, fs::vfs_open("/dev/null")->ind, 0, 1, 0);
  54. assert_likely(ret == GB_OK);
  55. d->eip = (void*)hdr.entry;
  56. d->sp = reinterpret_cast<uint32_t*>(types::elf::ELF_STACK_BOTTOM);
  57. auto* sp = &d->sp;
  58. types::vector<const char*> arr;
  59. for (const char** ptr = d->argv; *ptr != nullptr; ++ptr) {
  60. auto len = strlen(*ptr);
  61. *sp -= (len + 1);
  62. *sp = (uint32_t*)((uint32_t)*sp & 0xfffffff0);
  63. memcpy((char*)*sp, *ptr, len + 1);
  64. arr.push_back((const char*)*sp);
  65. }
  66. *sp -= sizeof(const char*) * arr.size();
  67. *sp = (uint32_t*)((uint32_t)*sp & 0xfffffff0);
  68. memcpy((char*)*sp, arr.data(), sizeof(const char*) * arr.size());
  69. _user_push(sp, 0);
  70. _user_push(sp, 0);
  71. _user_push(sp, *sp + 8);
  72. _user_push(sp, arr.size());
  73. return GB_OK;
  74. }