elf_parser.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright (C) 2021 Ant Group. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <fcntl.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include <errno.h>
  12. #include <stdbool.h>
  13. #include <elf.h>
  14. #include "aot_runtime.h"
  15. #include "bh_log.h"
  16. #include "elf_parser.h"
  17. bool
  18. is_ELF(void *buf)
  19. {
  20. Elf32_Ehdr *eh = (Elf32_Ehdr *)buf;
  21. if (!strncmp((char *)eh->e_ident, "\177ELF", 4)) {
  22. LOG_VERBOSE("the buffer is ELF entry!");
  23. return true;
  24. }
  25. LOG_VERBOSE("the buffer is not ELF entry!");
  26. return false;
  27. }
  28. static bool
  29. is64Bit(Elf32_Ehdr *eh)
  30. {
  31. if (eh->e_ident[EI_CLASS] == ELFCLASS64)
  32. return true;
  33. else
  34. return false;
  35. }
  36. static bool
  37. is32Bit(Elf32_Ehdr *eh)
  38. {
  39. if (eh->e_ident[EI_CLASS] == ELFCLASS32)
  40. return true;
  41. else
  42. return false;
  43. }
  44. bool
  45. is_ELF64(void *buf)
  46. {
  47. Elf64_Ehdr *eh = (Elf64_Ehdr *)buf;
  48. if (!strncmp((char *)eh->e_ident, "\177ELF", 4)) {
  49. LOG_VERBOSE("the buffer is ELF entry!");
  50. return true;
  51. }
  52. LOG_VERBOSE("the buffer is not ELF entry!");
  53. return false;
  54. }
  55. static void
  56. read_section_header_table(Elf32_Ehdr *eh, Elf32_Shdr *sh_table[])
  57. {
  58. uint32_t i;
  59. char *buf = (char *)eh;
  60. buf += eh->e_shoff;
  61. LOG_VERBOSE("str index = %d count=%d", eh->e_shstrndx, eh->e_shnum);
  62. for (i = 0; i < eh->e_shnum; i++) {
  63. sh_table[i] = (Elf32_Shdr *)buf;
  64. buf += eh->e_shentsize;
  65. }
  66. }
  67. static void
  68. read_section_header_table64(Elf64_Ehdr *eh, Elf64_Shdr *sh_table[])
  69. {
  70. uint32_t i;
  71. char *buf = (char *)eh;
  72. buf += eh->e_shoff;
  73. for (i = 0; i < eh->e_shnum; i++) {
  74. sh_table[i] = (Elf64_Shdr *)buf;
  75. buf += eh->e_shentsize;
  76. }
  77. }
  78. static char *
  79. get_section(Elf32_Ehdr *eh, Elf32_Shdr *section_header)
  80. {
  81. char *buf = (char *)eh;
  82. return buf + section_header->sh_offset;
  83. }
  84. static char *
  85. get_section64(Elf64_Ehdr *eh, Elf64_Shdr *section_header)
  86. {
  87. char *buf = (char *)eh;
  88. return buf + section_header->sh_offset;
  89. }
  90. bool
  91. get_text_section(void *buf, uint64_t *offset, uint64_t *size)
  92. {
  93. bool ret = false;
  94. uint32 i;
  95. char *sh_str;
  96. if (is64Bit(buf)) {
  97. Elf64_Ehdr *eh = (Elf64_Ehdr *)buf;
  98. Elf64_Shdr **sh_table =
  99. wasm_runtime_malloc(eh->e_shnum * sizeof(Elf64_Shdr *));
  100. if (sh_table) {
  101. read_section_header_table64(eh, sh_table);
  102. sh_str = get_section64(eh, sh_table[eh->e_shstrndx]);
  103. for (i = 0; i < eh->e_shnum; i++) {
  104. if (!strcmp(sh_str + sh_table[i]->sh_name, ".text")) {
  105. *offset = sh_table[i]->sh_offset;
  106. *size = sh_table[i]->sh_size;
  107. sh_table[i]->sh_addr =
  108. (Elf64_Addr)(uintptr_t)((char *)buf
  109. + sh_table[i]->sh_offset);
  110. ret = true;
  111. break;
  112. }
  113. }
  114. wasm_runtime_free(sh_table);
  115. }
  116. }
  117. else if (is32Bit(buf)) {
  118. Elf32_Ehdr *eh = (Elf32_Ehdr *)buf;
  119. Elf32_Shdr **sh_table =
  120. wasm_runtime_malloc(eh->e_shnum * sizeof(Elf32_Shdr *));
  121. if (sh_table) {
  122. read_section_header_table(eh, sh_table);
  123. sh_str = get_section(eh, sh_table[eh->e_shstrndx]);
  124. for (i = 0; i < eh->e_shnum; i++) {
  125. if (!strcmp(sh_str + sh_table[i]->sh_name, ".text")) {
  126. *offset = sh_table[i]->sh_offset;
  127. *size = sh_table[i]->sh_size;
  128. sh_table[i]->sh_addr =
  129. (Elf32_Addr)(uintptr_t)((char *)buf
  130. + sh_table[i]->sh_offset);
  131. ret = true;
  132. break;
  133. }
  134. }
  135. wasm_runtime_free(sh_table);
  136. }
  137. }
  138. return ret;
  139. }