SimpleKernel  0.0.1
Elf Class Reference

#include <load_elf.h>

Collaboration diagram for Elf:
Collaboration graph

Public Member Functions

 Elf (wchar_t *_kernel_image_filename)
 
 ~Elf ()
 
auto load_kernel_image () const -> uint64_t
 
auto load () const -> uintptr_t
 
不使用的构造函数
 Elf (const Elf &)=delete
 
 Elf (Elf &&)=delete
 
auto operator= (const Elf &) -> Elf &=delete
 
auto operator= (Elf &&) -> Elf &=delete
 

Private Member Functions

auto get_file_size () const -> size_t
 
auto check_elf_identity () const -> bool
 
void get_ehdr ()
 
void print_ehdr () const
 
void get_phdr ()
 
void print_phdr () const
 
void get_shdr ()
 
void print_shdr () const
 
void load_sections (const Elf64_Phdr &_phdr) const
 
void load_program_sections () const
 

elf 文件相关

EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * file_system_protocol = nullptr
 
EFI_FILE * root_file_system = nullptr
 
EFI_FILE * elf = nullptr
 elf 文件指针 More...
 
size_t elf_file_size = 0
 elf 文件大小 More...
 
void * elf_file_buffer = nullptr
 elf 文件内容缓冲区 More...
 
std::span< uint8_t > file = {}
 elf 文件访问 More...
 
Elf64_Ehdr ehdr = {}
 
std::span< Elf64_Phdr > phdr = {}
 
std::span< Elf64_Shdr > shdr = {}
 
std::array< uint8_t, SECTION_BUF_SIZEshstrtab_buf = {}
 shstrtab 缓冲 More...
 
static constexpr const size_t SECTION_BUF_SIZE = 1024
 section 缓冲区大小 More...
 

Detailed Description

elf 文件相关

Definition at line 131 of file load_elf.h.

Constructor & Destructor Documentation

◆ Elf() [1/3]

Elf::Elf ( wchar_t *  _kernel_image_filename)
explicit

构造函数

Parameters
_kernel_image_filename要加载的内核文件

Definition at line 51 of file load_elf.cpp.

51  {
52  EFI_STATUS status = EFI_SUCCESS;
53  // 打开文件系统协议
54  status = LibLocateProtocol(&FileSystemProtocol,
55  reinterpret_cast<void **>(&file_system_protocol));
56  if (EFI_ERROR(status)) {
57  debug << L"LibLocateProtocol failed: " << status << ostream::endl;
58  throw std::runtime_error("EFI_ERROR(status)");
59  }
60 
61  // 打开根文件系统
62  status = uefi_call_wrapper(file_system_protocol->OpenVolume, 2,
64  if (EFI_ERROR(status)) {
65  debug << L"OpenVolume failed: " << status << ostream::endl;
66  throw std::runtime_error("EFI_ERROR(status)");
67  }
68 
69  // 打开 elf 文件
70  status = uefi_call_wrapper(root_file_system->Open, 5, root_file_system, &elf,
71  _kernel_image_filename, EFI_FILE_MODE_READ,
72  EFI_FILE_READ_ONLY);
73 
74  if (EFI_ERROR(status)) {
75  debug << L"Open failed: " << status << ostream::endl;
76  throw std::runtime_error("EFI_ERROR(status)");
77  }
78 
79  // 获取 elf 文件大小
80  try {
82  } catch (std::runtime_error &_e) {
83  debug << L"get_file_size failed: " << _e.what() << ostream::endl;
84  throw std::runtime_error(_e.what());
85  }
86  debug << L"Kernel file size: " << elf_file_size << ostream::endl;
87 
88  // 分配 elf 文件缓存
89  status = uefi_call_wrapper(gBS->AllocatePool, 3, EfiLoaderData, elf_file_size,
91 
92  if (EFI_ERROR(status)) {
93  debug << L"AllocatePool failed: " << status << ostream::endl;
94  throw std::runtime_error("EFI_ERROR(status)");
95  }
96 
97  // 将内核文件读入内存
98  status = uefi_call_wrapper(elf->Read, 3, (EFI_FILE *)elf, &elf_file_size,
100  if (EFI_ERROR(status)) {
101  debug << L"Read failed: " << status << ostream::endl;
102  throw std::runtime_error("EFI_ERROR(status)");
103  }
104 
105  file = std::span<uint8_t>(static_cast<uint8_t *>(elf_file_buffer),
106  elf_file_size);
107 
108  // 检查 elf 头数据
109  auto check_elf_identity_ret = check_elf_identity();
110  if (!check_elf_identity_ret) {
111  debug << L"NOT valid ELF file" << ostream::endl;
112  throw std::runtime_error("check_elf_identity_ret == false");
113  }
114 
115  // 读取 ehdr
116  get_ehdr();
117  print_ehdr();
118  // 读取 phdr
119  get_phdr();
120  print_phdr();
121  // 读取 shdr
122  get_shdr();
123  print_shdr();
124 }
auto check_elf_identity() const -> bool
Definition: load_elf.cpp:210
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * file_system_protocol
Definition: load_elf.h:166
void get_shdr()
Definition: load_elf.cpp:530
auto get_file_size() const -> size_t
Definition: load_elf.cpp:203
EFI_FILE * root_file_system
Definition: load_elf.h:167
size_t elf_file_size
elf 文件大小
Definition: load_elf.h:171
void print_shdr() const
Definition: load_elf.cpp:539
void get_phdr()
Definition: load_elf.cpp:390
void print_ehdr() const
Definition: load_elf.cpp:233
void * elf_file_buffer
elf 文件内容缓冲区
Definition: load_elf.h:173
EFI_FILE * elf
elf 文件指针
Definition: load_elf.h:169
std::span< uint8_t > file
elf 文件访问
Definition: load_elf.h:175
void get_ehdr()
Definition: load_elf.cpp:229
void print_phdr() const
Definition: load_elf.cpp:395
static auto endl(ostream &_ostream) -> ostream &
Definition: ostream.cpp:42
static ostream debug
全局输出流
Definition: ostream.hpp:194
Here is the call graph for this function:

◆ ~Elf()

Elf::~Elf ( )

析构函数

Note
elf_file_buffer 不会被释放

Definition at line 126 of file load_elf.cpp.

126  {
127  try {
128  EFI_STATUS status = EFI_SUCCESS;
129  // 关闭 elf 文件
130  status = uefi_call_wrapper(elf->Close, 1, elf);
131  if (EFI_ERROR(status)) {
132  debug << L"Close failed: " << status << ostream::endl;
133  throw std::runtime_error("EFI_ERROR(status)");
134  }
136  } catch (std::runtime_error &_e) {
137  debug << L"~Elf failed: " << _e.what() << ostream::endl;
138  }
139 }
Here is the call graph for this function:

◆ Elf() [2/3]

Elf::Elf ( const Elf )
delete

◆ Elf() [3/3]

Elf::Elf ( Elf &&  )
delete

Member Function Documentation

◆ check_elf_identity()

auto Elf::check_elf_identity ( ) const -> bool
private

检查 elf 标识

Returns
失败返回 false

Definition at line 210 of file load_elf.cpp.

210  {
211  if ((file[EI_MAG0] != ELFMAG0) || (file[EI_MAG1] != ELFMAG1) ||
212  (file[EI_MAG2] != ELFMAG2) || (file[EI_MAG3] != ELFMAG3)) {
213  debug << L"Fatal Error: Invalid ELF header" << ostream::endl;
214  return false;
215  }
216  if (file[EI_CLASS] == ELFCLASS32) {
217  debug << L"Found 32bit executable but NOT SUPPORT" << ostream::endl;
218  return false;
219  }
220  if (file[EI_CLASS] == ELFCLASS64) {
221  debug << L"Found 64bit executable" << ostream::endl;
222  } else {
223  debug << L"Fatal Error: Invalid executable" << ostream::endl;
224  return false;
225  }
226  return true;
227 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_ehdr()

void Elf::get_ehdr ( )
private

读取 elf 文件的 ehdr

Definition at line 229 of file load_elf.cpp.

229  {
230  ehdr = *reinterpret_cast<const Elf64_Ehdr *>(file.data());
231 }
Elf64_Ehdr ehdr
Definition: load_elf.h:176
Here is the caller graph for this function:

◆ get_file_size()

auto Elf::get_file_size ( ) const -> size_t
private

获取文件大小

Returns
文件大小

Definition at line 203 of file load_elf.cpp.

203  {
204  // 获取 elf 文件大小
205  auto *elf_file_info = LibFileInfo(elf);
206  auto file_size = elf_file_info->FileSize;
207  return file_size;
208 }
Here is the caller graph for this function:

◆ get_phdr()

void Elf::get_phdr ( )
private

读取 elf 文件的 phdr

Definition at line 390 of file load_elf.cpp.

390  {
391  phdr = std::span<Elf64_Phdr>(
392  reinterpret_cast<Elf64_Phdr *>(file.data() + ehdr.e_phoff), ehdr.e_phnum);
393 }
std::span< Elf64_Phdr > phdr
Definition: load_elf.h:177
Here is the caller graph for this function:

◆ get_shdr()

void Elf::get_shdr ( )
private

读取 elf 文件的 shdr

Definition at line 530 of file load_elf.cpp.

530  {
531  shdr = std::span<Elf64_Shdr>(
532  reinterpret_cast<Elf64_Shdr *>(file.data() + ehdr.e_shoff), ehdr.e_shnum);
533  // 将 shstrtab 的内容复制到 shstrtab_buf 中
534 
535  memcpy(shstrtab_buf.data(), file.data() + shdr[ehdr.e_shstrndx].sh_offset,
536  shdr[ehdr.e_shstrndx].sh_size);
537 }
std::span< Elf64_Shdr > shdr
Definition: load_elf.h:178
std::array< uint8_t, SECTION_BUF_SIZE > shstrtab_buf
shstrtab 缓冲
Definition: load_elf.h:182
Here is the caller graph for this function:

◆ load()

auto Elf::load ( ) const -> uintptr_t

将 elf 文件加载进内存

Definition at line 181 of file load_elf.cpp.

181  {
182  // 记录 AllocatePages 分配出的物理地址
183  uintptr_t image_base = 0;
184  // 计算需要的内存页
185  auto section_page_count = EFI_SIZE_TO_PAGES(elf_file_size);
186  // 将整个 elf 文件映射到内存,方便后续读取
187  auto status =
188  uefi_call_wrapper(gBS->AllocatePages, 4, AllocateAnyPages, EfiLoaderCode,
189  section_page_count, &image_base);
190  if (EFI_ERROR(status)) {
191  debug << L"AllocatePages failed: " << status << ostream::endl;
192  throw std::runtime_error("EFI_ERROR(status)");
193  }
194  // 将 elf 复制到分配的物理内存中
195  std::memcpy(reinterpret_cast<void *>(image_base), file.data(),
196  section_page_count * EFI_PAGE_SIZE);
197 
198  debug << L"AllocatePages section_page_count: " << section_page_count
199  << L" image_base: " << ostream::hex_X << image_base << ostream::endl;
200  return image_base + ehdr.e_entry;
201 }
static auto hex_X(ostream &_ostream) -> ostream &
Definition: ostream.cpp:37
Here is the call graph for this function:

◆ load_kernel_image()

auto Elf::load_kernel_image ( ) const -> uint64_t

加载 elf 内核

Returns
内核入口点

Definition at line 141 of file load_elf.cpp.

141  {
142  uintptr_t image_base = 0;
143  uintptr_t image_begin = 0;
144  try {
145  // load_program_sections();
146  size_t size = 0;
147  for (uint64_t i = 0; i < ehdr.e_phnum; i++) {
148  if (phdr[i].p_type != PT_LOAD) {
149  continue;
150  }
151  phdr[i].p_vaddr;
152  size += phdr[i].p_memsz;
153  }
154  auto section_page_count = EFI_SIZE_TO_PAGES(size);
155  auto status =
156  uefi_call_wrapper(gBS->AllocatePages, 4, AllocateAnyPages,
157  EfiLoaderCode, section_page_count, &image_base);
158  if (EFI_ERROR(status)) {
159  debug << L"AllocatePages failed: " << status << ostream::endl;
160  throw std::runtime_error("EFI_ERROR(status)");
161  }
162 
163  for (auto &i : phdr) {
164  if (i.p_type != PT_LOAD) {
165  continue;
166  }
167  memcpy((void *)(image_base + i.p_vaddr), file.data() + i.p_offset,
168  i.p_memsz);
169  }
170 
171  } catch (std::runtime_error &_e) {
172  debug << L"load_kernel_image: " << _e.what() << ostream::endl;
173  }
174  debug << L"load_kernel_image: " << ostream::hex_X << image_base << L" "
175  << ostream::hex_X << ehdr.e_entry << L" " << ostream::hex_X
176  << image_begin << ostream::endl;
177 
178  return image_base + ehdr.e_entry - image_begin;
179 }
Here is the call graph for this function:

◆ load_program_sections()

void Elf::load_program_sections ( ) const
private

加载程序段

Definition at line 885 of file load_elf.cpp.

885  {
886  uint64_t loaded = 0;
887  for (uint64_t i = 0; i < ehdr.e_phnum; i++) {
888  if (phdr[i].p_type != PT_LOAD) {
889  continue;
890  }
891  load_sections(phdr[i]);
892  loaded++;
893  }
894 
895  if (loaded == 0) {
896  debug << L"Fatal Error: No loadable program segments found in Kernel image "
897  << ostream::endl;
898  throw std::runtime_error("loaded == 0");
899  }
900 }
void load_sections(const Elf64_Phdr &_phdr) const
Definition: load_elf.cpp:815
Here is the call graph for this function:

◆ load_sections()

void Elf::load_sections ( const Elf64_Phdr &  _phdr) const
private

将 elf 段加载到内存

Parameters
_phdr要加载的程序段 phdr

Definition at line 815 of file load_elf.cpp.

815  {
816  EFI_STATUS status = EFI_SUCCESS;
817  void *data = nullptr;
818  // 计算使用的内存页数
819  auto section_page_count = EFI_SIZE_TO_PAGES(_phdr.p_memsz);
820 
821  // 设置文件偏移到 p_offset
822  status = uefi_call_wrapper(elf->SetPosition, 2, elf, _phdr.p_offset);
823  if (EFI_ERROR(status)) {
824  debug << L"SetPosition failed: " << status << ostream::endl;
825  throw std::runtime_error("memory_map == nullptr");
826  }
827  uintptr_t aaa = 0;
828  // status = uefi_call_wrapper(gBS->AllocatePages, 4, AllocateAddress,
829  // EfiLoaderData, section_page_count,
830  // (EFI_PHYSICAL_ADDRESS*)&_phdr.p_paddr);
831  status = uefi_call_wrapper(gBS->AllocatePages, 4, AllocateAnyPages,
832  EfiLoaderData, section_page_count, &aaa);
833  debug << L"_phdr.p_paddr: [" << status << L"] [" << section_page_count
834  << L"] " << ostream::hex_X << aaa << ostream::endl;
835  if (EFI_ERROR(status)) {
836  debug << L"AllocatePages AllocateAddress failed: " << status
837  << ostream::endl;
838  throw std::runtime_error("EFI_ERROR(status)");
839  }
840 
841  if (_phdr.p_filesz > 0) {
842  auto buffer_read_size = _phdr.p_filesz;
843  // 为 program_data 分配内存
844  status = uefi_call_wrapper(gBS->AllocatePool, 3, EfiLoaderCode,
845  buffer_read_size, (void **)&data);
846  if (EFI_ERROR(status)) {
847  debug << L"AllocatePool failed: " << status << ostream::endl;
848  throw std::runtime_error("EFI_ERROR(status)");
849  }
850  // 读数据
851  status =
852  uefi_call_wrapper(elf->Read, 3, elf, &buffer_read_size, (void *)data);
853  if (EFI_ERROR(status)) {
854  debug << L"Read failed: " << status << ostream::endl;
855  throw std::runtime_error("EFI_ERROR(status)");
856  }
857 
858  // 将读出来的数据复制到其对应的物理地址
859  uefi_call_wrapper(gBS->CopyMem, 3,
860  reinterpret_cast<void *>(aaa + _phdr.p_paddr), data,
861  _phdr.p_filesz);
862 
863  // 释放 program_data
864  status = uefi_call_wrapper(gBS->FreePool, 1, data);
865  if (EFI_ERROR(status)) {
866  debug << L"FreePool failed: " << status << ostream::endl;
867  throw std::runtime_error("EFI_ERROR(status)");
868  }
869  }
870 
871  // 计算填充大小
872  auto *zero_fill_start =
873  reinterpret_cast<void *>(aaa + _phdr.p_paddr + _phdr.p_filesz);
874  auto zero_fill_count = _phdr.p_memsz - _phdr.p_filesz;
875  if (zero_fill_count > 0) {
876  debug << L"Debug: Zero-filling " << zero_fill_count
877  << L" bytes at address '" << ostream::hex_x << zero_fill_start << L"'"
878  << ostream::endl;
879 
880  // 将填充部分置 0
881  uefi_call_wrapper(gBS->SetMem, 3, zero_fill_start, zero_fill_count, 0);
882  }
883 }
static auto hex_x(ostream &_ostream) -> ostream &
Definition: ostream.cpp:32
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=() [1/2]

auto Elf::operator= ( const Elf ) -> Elf &=delete
delete

◆ operator=() [2/2]

auto Elf::operator= ( Elf &&  ) -> Elf &=delete
delete

◆ print_ehdr()

void Elf::print_ehdr ( ) const
private

输出 elf ehdr

Definition at line 233 of file load_elf.cpp.

233  {
234  debug << L" Magic: ";
235  for (auto idx : ehdr.e_ident) {
236  debug << ostream::hex_x << idx << L" ";
237  }
238  debug << ostream::endl;
239 
240  debug << L" Class: ";
241  switch (ehdr.e_ident[EI_CLASS]) {
242  case ELFCLASSNONE: {
243  debug << L"Invalid class";
244  break;
245  }
246  case ELFCLASS32: {
247  debug << L"ELF32";
248  break;
249  }
250  case ELFCLASS64: {
251  debug << L"ELF64";
252  break;
253  }
254  default: {
255  debug << ehdr.e_ident[EI_CLASS];
256  break;
257  }
258  }
259  debug << ostream::endl;
260 
261  debug << L" Data: ";
262  switch (ehdr.e_ident[EI_DATA]) {
263  case ELFDATANONE: {
264  debug << L"Invalid data encoding";
265  break;
266  }
267  case ELFDATA2LSB: {
268  debug << L"2's complement, little endian";
269  break;
270  }
271  case ELFDATA2MSB: {
272  debug << L"2's complement, big endian";
273  break;
274  }
275  default: {
276  debug << ehdr.e_ident[EI_DATA];
277  break;
278  }
279  }
280  debug << ostream::endl;
281 
282  debug << L" Version: "
283  << ehdr.e_ident[EI_VERSION] << L" ";
284  switch (ehdr.e_ident[EI_VERSION]) {
285  case EV_NONE: {
286  debug << L"Invalid ELF version";
287  break;
288  }
289  case EV_CURRENT: {
290  debug << L"Current version";
291  break;
292  }
293  default: {
294  debug << ehdr.e_ident[EI_VERSION];
295  break;
296  }
297  }
298  debug << ostream::endl;
299 
300  debug << L" OS/ABI: ";
301  switch (ehdr.e_ident[EI_OSABI]) {
302  case ELFOSABI_SYSV: {
303  debug << L"UNIX System V ABI";
304  break;
305  }
306  default: {
307  debug << ehdr.e_ident[EI_OSABI];
308  break;
309  }
310  }
311  debug << ostream::endl;
312 
313  debug << L" ABI Version: "
314  << ehdr.e_ident[EI_ABIVERSION] << ostream::endl;
315 
316  debug << L" Type: ";
317  switch (ehdr.e_type) {
318  case ET_NONE: {
319  debug << L"No file type";
320  break;
321  }
322  case ET_REL: {
323  debug << L"Relocatable file";
324  break;
325  }
326  case ET_EXEC: {
327  debug << L"Executable file";
328  break;
329  }
330  case ET_DYN: {
331  debug << L"DYN (Shared object file)";
332  break;
333  }
334  case ET_CORE: {
335  debug << L"Core file";
336  break;
337  }
338  default: {
339  debug << ehdr.e_type;
340  break;
341  }
342  }
343  debug << ostream::endl;
344 
345  debug << L" Machine: ";
346  switch (ehdr.e_machine) {
347  case EM_X86_64: {
348  debug << L"AMD x86-64 architecture";
349  break;
350  }
351  case EM_RISCV: {
352  debug << L"RISC-V";
353  break;
354  }
355  case EM_AARCH64: {
356  debug << L"ARM AARCH64";
357  break;
358  }
359  default: {
360  debug << ehdr.e_machine;
361  break;
362  }
363  }
364  debug << ostream::endl;
365 
366  debug << L" Version: " << ostream::hex_x
367  << ehdr.e_version << ostream::endl;
368  debug << L" Entry point address: " << ostream::hex_x
369  << ehdr.e_entry << ostream::endl;
370  debug << L" Start of program headers: " << ehdr.e_phoff
371  << L" (bytes into file)" << ostream::endl;
372  debug << L" Start of section headers: " << ehdr.e_shoff
373  << L" (bytes into file)" << ostream::endl;
374  debug << L" Flags: " << ostream::hex_x
375  << ehdr.e_flags << ostream::endl;
376  debug << L" Size of this header: " << ehdr.e_ehsize
377  << L" (bytes)" << ostream::endl;
378  debug << L" Size of program headers: " << ehdr.e_phentsize
379  << L" (bytes)" << ostream::endl;
380  debug << L" Number of program headers: " << ehdr.e_phnum
381  << ostream::endl;
382  debug << L" Size of section headers: " << ehdr.e_shentsize
383  << L" (bytes)" << ostream::endl;
384  debug << L" Number of section headers: " << ehdr.e_shnum
385  << ostream::endl;
386  debug << L" Section header string table index: " << ehdr.e_shstrndx
387  << ostream::endl;
388 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_phdr()

void Elf::print_phdr ( ) const
private

输出 phdr

Definition at line 395 of file load_elf.cpp.

395  {
396  debug << L"\nProgram Headers:" << ostream::endl;
397  debug << L" "
398  L"Type\t\tOffset\t\tVirtAddr\tPhysAddr\tFileSiz\t\tMemSiz\t\tFlags"
399  L"\tAlign"
400  << ostream::endl;
401  for (uint64_t i = 0; i < ehdr.e_phnum; i++) {
402  switch (phdr[i].p_type) {
403  case PT_NULL: {
404  debug << L" NULL\t\t";
405  break;
406  }
407 
408  case PT_LOAD: {
409  debug << L" LOAD\t\t";
410  break;
411  }
412  case PT_DYNAMIC: {
413  debug << L" DYNAMIC\t";
414  break;
415  }
416  case PT_INTERP: {
417  debug << L" INTERP\t";
418  break;
419  }
420  case PT_NOTE: {
421  debug << L" NOTE\t\t";
422  break;
423  }
424  case PT_SHLIB: {
425  debug << L" SHLIB\t\t";
426  break;
427  }
428  case PT_PHDR: {
429  debug << L" PHDR\t\t";
430  break;
431  }
432  case PT_TLS: {
433  debug << L" TLS\t\t";
434  break;
435  }
436  case PT_NUM: {
437  debug << L" NUM\t\t";
438  break;
439  }
440  case PT_LOOS: {
441  debug << L" LOOS\t\t";
442  break;
443  }
444  case PT_GNU_EH_FRAME: {
445  debug << L" GNU_EH_FRAME\t";
446  break;
447  }
448  case PT_GNU_STACK: {
449  debug << L" GNU_STACK\t";
450  break;
451  }
452  case PT_GNU_RELRO: {
453  debug << L" GNU_RELRO\t";
454  break;
455  }
456  case PT_GNU_PROPERTY: {
457  debug << L" GNU_PROPERTY\t";
458  break;
459  }
460  case PT_SUNWBSS: {
461  debug << L" SUNWBSS\t\t";
462  break;
463  }
464  case PT_SUNWSTACK: {
465  debug << L" SUNWSTACK\t";
466  break;
467  }
468  case PT_HIOS: {
469  debug << L" HIOS\t\t";
470  break;
471  }
472  case PT_LOPROC: {
473  debug << L" LOPROC\t\t";
474  break;
475  }
476  case PT_HIPROC: {
477  debug << L" HIPROC\t\t";
478  break;
479  }
480  default: {
481  debug << L" Unknown " << ostream::hex_X << phdr[i].p_type << L"\t";
482  break;
483  }
484  }
485 
486  debug << ostream::hex_X << phdr[i].p_offset << L"\t";
487  debug << ostream::hex_X << phdr[i].p_vaddr << L"\t";
488  debug << ostream::hex_X << phdr[i].p_paddr << L"\t";
489  debug << ostream::hex_X << phdr[i].p_filesz << L"\t";
490  debug << ostream::hex_X << phdr[i].p_memsz << L"\t";
491 
492  switch (phdr[i].p_flags) {
493  case PF_X: {
494  debug << L"E\t";
495  break;
496  }
497  case PF_W: {
498  debug << L"W\t";
499  break;
500  }
501  case PF_R: {
502  debug << L"R\t";
503  break;
504  }
505  case PF_MASKOS: {
506  debug << L"OS-specific\t";
507  break;
508  }
509  case PF_MASKPROC: {
510  debug << L"Processor-specific\t";
511  break;
512  }
513  case (PF_X | PF_R): {
514  debug << L"R E\t";
515  break;
516  }
517  case (PF_W | PF_R): {
518  debug << L"RW\t";
519  break;
520  }
521  default: {
522  debug << L"Unknown " << ostream::hex_x << phdr[i].p_flags << L"\t";
523  break;
524  }
525  }
526  debug << ostream::hex_x << phdr[i].p_align << ostream::endl;
527  }
528 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_shdr()

void Elf::print_shdr ( ) const
private

输出 shdr

Definition at line 539 of file load_elf.cpp.

539  {
540  debug << L"\nSection Headers:" << ostream::endl;
541  debug << L" [Nr] "
542  L"Name\t\t\tType\t\tAddress\t\tOffset\t\tSize\t\tEntSize\t\tFl"
543  L"ags\tLink\tInfo\tAlign"
544  << ostream::endl;
545  for (uint64_t i = 0; i < ehdr.e_shnum; i++) {
546  debug << L" [";
547  // 对齐
548  if (i < ALIGN_TWO) {
549  debug << L" ";
550  }
551  debug << i << L"] ";
552 
553  std::array<wchar_t, SECTION_BUF_SIZE> buf = {0};
554  auto char2wchar_ret = char2wchar(
555  buf.data(),
556  reinterpret_cast<const char *>(shstrtab_buf.data() + shdr[i].sh_name));
557  debug << (const wchar_t *)buf.data() << L"\t";
558 
559  if (char2wchar_ret <= TWO_TAB_SIZE) {
560  debug << L"\t";
561  }
562  if (char2wchar_ret <= ONE_TAB_SIZE) {
563  debug << L"\t";
564  }
565  if (char2wchar_ret <= 1) {
566  debug << L"\t";
567  }
568  switch (shdr[i].sh_type) {
569  case SHT_NULL: {
570  debug << L"NULL\t\t";
571  break;
572  }
573  case SHT_PROGBITS: {
574  debug << L"PROGBITS\t";
575  break;
576  }
577  case SHT_SYMTAB: {
578  debug << L"SYMTAB\t\t";
579  break;
580  }
581  case SHT_STRTAB: {
582  debug << L"STRTAB\t\t";
583  break;
584  }
585  case SHT_RELA: {
586  debug << L"RELA\t\t";
587  break;
588  }
589  case SHT_HASH: {
590  debug << L"HASH\t\t";
591  break;
592  }
593  case SHT_DYNAMIC: {
594  debug << L"DYNAMIC\t\t";
595  break;
596  }
597  case SHT_NOTE: {
598  debug << L"NOTE\t\t";
599  break;
600  }
601  case SHT_NOBITS: {
602  debug << L"NOBITS\t\t";
603  break;
604  }
605  case SHT_REL: {
606  debug << L"REL\t\t";
607  break;
608  }
609  case SHT_SHLIB: {
610  debug << L"SHLIB\t\t";
611  break;
612  }
613  case SHT_DYNSYM: {
614  debug << L"DYNSYM\t\t";
615  break;
616  }
617  case SHT_INIT_ARRAY: {
618  debug << L"INIT_ARRAY\t";
619  break;
620  }
621  case SHT_FINI_ARRAY: {
622  debug << L"FINI_ARRAY\t";
623  break;
624  }
625  case SHT_PREINIT_ARRAY: {
626  debug << L"PREINIT_ARRAY\t\t";
627  break;
628  }
629  case SHT_GROUP: {
630  debug << L"GROUP\t\t";
631  break;
632  }
633  case SHT_SYMTAB_SHNDX: {
634  debug << L"SYMTAB_SHNDX\t\t";
635  break;
636  }
637  case SHT_RELR: {
638  debug << L"RELR\t\t";
639  break;
640  }
641  case SHT_NUM: {
642  debug << L"NUM\t\t";
643  break;
644  }
645  case SHT_LOOS: {
646  debug << L"LOOS\t\t";
647  break;
648  }
649  case SHT_GNU_ATTRIBUTES: {
650  debug << L"GNU_ATTRIBUTE\t\t";
651  break;
652  }
653  case SHT_GNU_HASH: {
654  debug << L"GNU_HASH\t";
655  break;
656  }
657  case SHT_GNU_LIBLIST: {
658  debug << L"GNU_LIBLIST\t\t";
659  break;
660  }
661  case SHT_CHECKSUM: {
662  debug << L"CHECKSUM\t\t";
663  break;
664  }
665  case SHT_SUNW_move: {
666  debug << L"SUNW_move\t\t";
667  break;
668  }
669  case SHT_SUNW_COMDAT: {
670  debug << L"SUNW_COMDAT\t\t";
671  break;
672  }
673  case SHT_SUNW_syminfo: {
674  debug << L"SUNW_syminfo\t\t";
675  break;
676  }
677  case SHT_GNU_verdef: {
678  debug << L"GNU_verdef\t\t";
679  break;
680  }
681  case SHT_GNU_verneed: {
682  debug << L"GNU_verneed\t";
683  break;
684  }
685  case SHT_GNU_versym: {
686  debug << L"GNU_versym\t";
687  break;
688  }
689  case SHT_LOPROC: {
690  debug << L"LOPROC\t\t";
691  break;
692  }
693  case SHT_HIPROC: {
694  debug << L"HIPROC\t\t";
695  break;
696  }
697  case SHT_LOUSER: {
698  debug << L"LOUSER\t\t";
699  break;
700  }
701  case SHT_HIUSER: {
702  debug << L"HIUSER\t\t";
703  break;
704  }
705  default: {
706  debug << L"Unknown " << ostream::hex_X << shdr[i].sh_type << L"\t";
707 
708  break;
709  }
710  }
711 
712  debug << ostream::hex_X << shdr[i].sh_addr << L"\t";
713  debug << ostream::hex_x << shdr[i].sh_offset << L"\t\t";
714  debug << ostream::hex_X << shdr[i].sh_size << L"\t";
715  debug << ostream::hex_X << shdr[i].sh_entsize << L"\t";
716 
717  switch (shdr[i].sh_flags) {
718  case 0: {
719  debug << L"0\t";
720  break;
721  }
722  case SHF_WRITE: {
723  debug << L"WRITE\t";
724  break;
725  }
726  case SHF_ALLOC: {
727  debug << L"A\t";
728  break;
729  }
730  case SHF_EXECINSTR: {
731  debug << L"EXECINSTR\t";
732  break;
733  }
734  case SHF_MERGE: {
735  debug << L"MERGE\t";
736  break;
737  }
738  case SHF_STRINGS: {
739  debug << L"STRINGS\t";
740  break;
741  }
742  case SHF_INFO_LINK: {
743  debug << L"INFO_LINK\t";
744  break;
745  }
746  case SHF_LINK_ORDER: {
747  debug << L"LINK_ORDER\t";
748  break;
749  }
750  case SHF_OS_NONCONFORMING: {
751  debug << L"OS_NONCONFORMING\t";
752  break;
753  }
754  case SHF_GROUP: {
755  debug << L"GROUP\t";
756  break;
757  }
758  case SHF_TLS: {
759  debug << L"TLS\t";
760  break;
761  }
762  case SHF_COMPRESSED: {
763  debug << L"COMPRESSED\t";
764  break;
765  }
766  case SHF_MASKOS: {
767  debug << L"MASKOS\t";
768  break;
769  }
770  case SHF_MASKPROC: {
771  debug << L"MASKPROC\t";
772  break;
773  }
774  case SHF_GNU_RETAIN: {
775  debug << L"GNU_RETAIN\t";
776  break;
777  }
778  case SHF_ORDERED: {
779  debug << L"ORDERED\t";
780  break;
781  }
782  case SHF_EXCLUDE: {
783  debug << L"EXCLUDE\t";
784  break;
785  }
786  case (SHF_WRITE | SHF_ALLOC): {
787  debug << L"WA\t";
788  break;
789  }
790  case (SHF_ALLOC | SHF_MERGE): {
791  debug << L"AM\t";
792  break;
793  }
794  case (SHF_ALLOC | SHF_EXECINSTR): {
795  debug << L"AX\t";
796  break;
797  }
798  case (SHF_MERGE | SHF_STRINGS): {
799  debug << L"MS\t";
800  break;
801  }
802  default: {
803  debug << L"Unknown " << ostream::hex_X << shdr[i].sh_flags << L"\t";
804  break;
805  }
806  }
807 
808  debug << shdr[i].sh_link << L"\t";
809  debug << shdr[i].sh_info << L"\t";
810  debug << shdr[i].sh_addralign << L"\t";
811  debug << ostream::endl;
812  }
813 }
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ ehdr

Elf64_Ehdr Elf::ehdr = {}
private

Definition at line 176 of file load_elf.h.

◆ elf

EFI_FILE* Elf::elf = nullptr
private

elf 文件指针

Definition at line 169 of file load_elf.h.

◆ elf_file_buffer

void* Elf::elf_file_buffer = nullptr
private

elf 文件内容缓冲区

Definition at line 173 of file load_elf.h.

◆ elf_file_size

size_t Elf::elf_file_size = 0
private

elf 文件大小

Definition at line 171 of file load_elf.h.

◆ file

std::span<uint8_t> Elf::file = {}
private

elf 文件访问

Definition at line 175 of file load_elf.h.

◆ file_system_protocol

EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* Elf::file_system_protocol = nullptr
private

Definition at line 166 of file load_elf.h.

◆ phdr

std::span<Elf64_Phdr> Elf::phdr = {}
private

Definition at line 177 of file load_elf.h.

◆ root_file_system

EFI_FILE* Elf::root_file_system = nullptr
private

Definition at line 167 of file load_elf.h.

◆ SECTION_BUF_SIZE

constexpr const size_t Elf::SECTION_BUF_SIZE = 1024
staticconstexprprivate

section 缓冲区大小

Definition at line 180 of file load_elf.h.

◆ shdr

std::span<Elf64_Shdr> Elf::shdr = {}
private

Definition at line 178 of file load_elf.h.

◆ shstrtab_buf

std::array<uint8_t, SECTION_BUF_SIZE> Elf::shstrtab_buf = {}
private

shstrtab 缓冲

Definition at line 182 of file load_elf.h.


The documentation for this class was generated from the following files: