* @brief ELF 文件相关 */
| 20 | * @brief ELF 文件相关 |
| 21 | */ |
| 22 | class KernelElf { |
| 23 | public: |
| 24 | /// 符号表 |
| 25 | std::span<Elf64_Sym> symtab{}; |
| 26 | /// 字符串表 |
| 27 | uint8_t* strtab{nullptr}; |
| 28 | |
| 29 | /** |
| 30 | * @brief 获取 elf 文件大小 |
| 31 | * @return elf 文件大小 |
| 32 | */ |
| 33 | [[nodiscard]] auto GetElfSize() const -> size_t { return elf_.size(); } |
| 34 | |
| 35 | /// @name 构造/析构函数 |
| 36 | /// @{ |
| 37 | |
| 38 | /** |
| 39 | * @brief 构造函数 |
| 40 | * @param elf_addr elf 地址 |
| 41 | */ |
| 42 | explicit KernelElf(uint64_t elf_addr) { |
| 43 | assert(elf_addr != 0U && "elf_addr is null"); |
| 44 | |
| 45 | elf_ = std::span<uint8_t>(reinterpret_cast<uint8_t*>(elf_addr), EI_NIDENT); |
| 46 | |
| 47 | // 检查 elf 头数据 |
| 48 | CheckElfIdentity().or_else([](Error err) -> Expected<void> { |
| 49 | klog::Err("KernelElf NOT valid ELF file: {}", err.message()); |
| 50 | while (true) { |
| 51 | cpu_io::Pause(); |
| 52 | } |
| 53 | return {}; |
| 54 | }); |
| 55 | |
| 56 | ehdr_ = *reinterpret_cast<const Elf64_Ehdr*>(elf_.data()); |
| 57 | |
| 58 | // 重新计算 elf 大小 |
| 59 | size_t max_size = EI_NIDENT; |
| 60 | if (ehdr_.e_phoff != 0) { |
| 61 | size_t ph_end = ehdr_.e_phoff + ehdr_.e_phnum * ehdr_.e_phentsize; |
| 62 | if (ph_end > max_size) { |
| 63 | max_size = ph_end; |
| 64 | } |
| 65 | } |
| 66 | if (ehdr_.e_shoff != 0) { |
| 67 | size_t sh_end = ehdr_.e_shoff + ehdr_.e_shnum * ehdr_.e_shentsize; |
| 68 | if (sh_end > max_size) { |
| 69 | max_size = sh_end; |
| 70 | } |
| 71 | const auto* shdrs = |
| 72 | reinterpret_cast<const Elf64_Shdr*>(elf_.data() + ehdr_.e_shoff); |
| 73 | for (int i = 0; i < ehdr_.e_shnum; ++i) { |
| 74 | size_t section_end = shdrs[i].sh_offset + shdrs[i].sh_size; |
| 75 | if (section_end > max_size) { |
| 76 | max_size = section_end; |
| 77 | } |
| 78 | } |
| 79 | } |
nothing calls this directly
no outgoing calls
no test coverage detected