Image.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <AK/Demangle.h>
  27. #include <AK/Memory.h>
  28. #include <AK/StringBuilder.h>
  29. #include <AK/StringView.h>
  30. #include <LibELF/Image.h>
  31. #include <LibELF/Validation.h>
  32. namespace ELF {
  33. Image::Image(const u8* buffer, size_t size, bool verbose_logging)
  34. : m_buffer(buffer)
  35. , m_size(size)
  36. , m_verbose_logging(verbose_logging)
  37. {
  38. parse();
  39. }
  40. Image::~Image()
  41. {
  42. }
  43. static const char* object_file_type_to_string(Elf32_Half type)
  44. {
  45. switch (type) {
  46. case ET_NONE:
  47. return "None";
  48. case ET_REL:
  49. return "Relocatable";
  50. case ET_EXEC:
  51. return "Executable";
  52. case ET_DYN:
  53. return "Shared object";
  54. case ET_CORE:
  55. return "Core";
  56. default:
  57. return "(?)";
  58. }
  59. }
  60. StringView Image::section_index_to_string(unsigned index) const
  61. {
  62. ASSERT(m_valid);
  63. if (index == SHN_UNDEF)
  64. return "Undefined";
  65. if (index >= SHN_LORESERVE)
  66. return "Reserved";
  67. return section(index).name();
  68. }
  69. unsigned Image::symbol_count() const
  70. {
  71. ASSERT(m_valid);
  72. return section(m_symbol_table_section_index).entry_count();
  73. }
  74. void Image::dump() const
  75. {
  76. dbgprintf("Image{%p} {\n", this);
  77. dbgprintf(" is_valid: %u\n", is_valid());
  78. if (!is_valid()) {
  79. dbgprintf("}\n");
  80. return;
  81. }
  82. dbgprintf(" type: %s\n", object_file_type_to_string(header().e_type));
  83. dbgprintf(" machine: %u\n", header().e_machine);
  84. dbgprintf(" entry: %x\n", header().e_entry);
  85. dbgprintf(" shoff: %u\n", header().e_shoff);
  86. dbgprintf(" shnum: %u\n", header().e_shnum);
  87. dbgprintf(" phoff: %u\n", header().e_phoff);
  88. dbgprintf(" phnum: %u\n", header().e_phnum);
  89. dbgprintf(" shstrndx: %u\n", header().e_shstrndx);
  90. for_each_program_header([&](const ProgramHeader& program_header) {
  91. dbgprintf(" Program Header %d: {\n", program_header.index());
  92. dbgprintf(" type: %x\n", program_header.type());
  93. dbgprintf(" offset: %x\n", program_header.offset());
  94. dbgprintf(" flags: %x\n", program_header.flags());
  95. dbgprintf(" \n");
  96. dbgprintf(" }\n");
  97. });
  98. for (unsigned i = 0; i < header().e_shnum; ++i) {
  99. auto& section = this->section(i);
  100. dbgprintf(" Section %u: {\n", i);
  101. dbgprintf(" name: %.*s\n", (int)section.name().length(), section.name().characters_without_null_termination());
  102. dbgprintf(" type: %x\n", section.type());
  103. dbgprintf(" offset: %x\n", section.offset());
  104. dbgprintf(" size: %u\n", section.size());
  105. dbgprintf(" \n");
  106. dbgprintf(" }\n");
  107. }
  108. dbgprintf("Symbol count: %u (table is %u)\n", symbol_count(), m_symbol_table_section_index);
  109. for (unsigned i = 1; i < symbol_count(); ++i) {
  110. auto& sym = symbol(i);
  111. dbgprintf("Symbol @%u:\n", i);
  112. dbgprintf(" Name: %.*s\n", (int)sym.name().length(), sym.name().characters_without_null_termination());
  113. StringView section_index_string = section_index_to_string(sym.section_index());
  114. dbgprintf(" In section: %.*s\n", (int)section_index_string.length(), section_index_string.characters_without_null_termination());
  115. dbgprintf(" Value: %x\n", sym.value());
  116. dbgprintf(" Size: %u\n", sym.size());
  117. }
  118. dbgprintf("}\n");
  119. }
  120. unsigned Image::section_count() const
  121. {
  122. ASSERT(m_valid);
  123. return header().e_shnum;
  124. }
  125. unsigned Image::program_header_count() const
  126. {
  127. ASSERT(m_valid);
  128. return header().e_phnum;
  129. }
  130. bool Image::parse()
  131. {
  132. if (m_size < sizeof(Elf32_Ehdr) || !validate_elf_header(header(), m_size, m_verbose_logging)) {
  133. if (m_verbose_logging)
  134. dbgputstr("Image::parse(): ELF Header not valid\n");
  135. return m_valid = false;
  136. }
  137. if (!validate_program_headers(header(), m_size, m_buffer, m_size, nullptr, m_verbose_logging)) {
  138. if (m_verbose_logging)
  139. dbgputstr("Image::parse(): ELF Program Headers not valid\n");
  140. return m_valid = false;
  141. }
  142. m_valid = true;
  143. // First locate the string tables.
  144. for (unsigned i = 0; i < section_count(); ++i) {
  145. auto& sh = section_header(i);
  146. if (sh.sh_type == SHT_SYMTAB) {
  147. if (m_symbol_table_section_index && m_symbol_table_section_index != i)
  148. return m_valid = false;
  149. m_symbol_table_section_index = i;
  150. }
  151. if (sh.sh_type == SHT_STRTAB && i != header().e_shstrndx) {
  152. if (section_header_table_string(sh.sh_name) == ELF_STRTAB)
  153. m_string_table_section_index = i;
  154. }
  155. }
  156. // Then create a name-to-index map.
  157. for (unsigned i = 0; i < section_count(); ++i) {
  158. auto& section = this->section(i);
  159. m_sections.set(section.name(), move(i));
  160. }
  161. return m_valid;
  162. }
  163. StringView Image::table_string(unsigned table_index, unsigned offset) const
  164. {
  165. ASSERT(m_valid);
  166. auto& sh = section_header(table_index);
  167. if (sh.sh_type != SHT_STRTAB)
  168. return nullptr;
  169. size_t computed_offset = sh.sh_offset + offset;
  170. if (computed_offset >= m_size) {
  171. if (m_verbose_logging)
  172. dbgprintf("SHENANIGANS! Image::table_string() computed offset outside image.\n");
  173. return {};
  174. }
  175. size_t max_length = m_size - computed_offset;
  176. size_t length = strnlen(raw_data(sh.sh_offset + offset), max_length);
  177. return { raw_data(sh.sh_offset + offset), length };
  178. }
  179. StringView Image::section_header_table_string(unsigned offset) const
  180. {
  181. ASSERT(m_valid);
  182. return table_string(header().e_shstrndx, offset);
  183. }
  184. StringView Image::table_string(unsigned offset) const
  185. {
  186. ASSERT(m_valid);
  187. return table_string(m_string_table_section_index, offset);
  188. }
  189. const char* Image::raw_data(unsigned offset) const
  190. {
  191. ASSERT(offset < m_size); // Callers must check indices into raw_data()'s result are also in bounds.
  192. return reinterpret_cast<const char*>(m_buffer) + offset;
  193. }
  194. const Elf32_Ehdr& Image::header() const
  195. {
  196. ASSERT(m_size >= sizeof(Elf32_Ehdr));
  197. return *reinterpret_cast<const Elf32_Ehdr*>(raw_data(0));
  198. }
  199. const Elf32_Phdr& Image::program_header_internal(unsigned index) const
  200. {
  201. ASSERT(m_valid);
  202. ASSERT(index < header().e_phnum);
  203. return *reinterpret_cast<const Elf32_Phdr*>(raw_data(header().e_phoff + (index * sizeof(Elf32_Phdr))));
  204. }
  205. const Elf32_Shdr& Image::section_header(unsigned index) const
  206. {
  207. ASSERT(m_valid);
  208. ASSERT(index < header().e_shnum);
  209. return *reinterpret_cast<const Elf32_Shdr*>(raw_data(header().e_shoff + (index * header().e_shentsize)));
  210. }
  211. const Image::Symbol Image::symbol(unsigned index) const
  212. {
  213. ASSERT(m_valid);
  214. ASSERT(index < symbol_count());
  215. auto* raw_syms = reinterpret_cast<const Elf32_Sym*>(raw_data(section(m_symbol_table_section_index).offset()));
  216. return Symbol(*this, index, raw_syms[index]);
  217. }
  218. const Image::Section Image::section(unsigned index) const
  219. {
  220. ASSERT(m_valid);
  221. ASSERT(index < section_count());
  222. return Section(*this, index);
  223. }
  224. const Image::ProgramHeader Image::program_header(unsigned index) const
  225. {
  226. ASSERT(m_valid);
  227. ASSERT(index < program_header_count());
  228. return ProgramHeader(*this, index);
  229. }
  230. FlatPtr Image::program_header_table_offset() const
  231. {
  232. return header().e_phoff;
  233. }
  234. const Image::Relocation Image::RelocationSection::relocation(unsigned index) const
  235. {
  236. ASSERT(index < relocation_count());
  237. auto* rels = reinterpret_cast<const Elf32_Rel*>(m_image.raw_data(offset()));
  238. return Relocation(m_image, rels[index]);
  239. }
  240. const Image::RelocationSection Image::Section::relocations() const
  241. {
  242. StringBuilder builder;
  243. builder.append(".rel");
  244. builder.append(name());
  245. auto relocation_section = m_image.lookup_section(builder.to_string());
  246. if (relocation_section.type() != SHT_REL)
  247. return static_cast<const RelocationSection>(m_image.section(0));
  248. #ifdef Image_DEBUG
  249. dbgprintf("Found relocations for %s in %s\n", name().to_string().characters(), relocation_section.name().to_string().characters());
  250. #endif
  251. return static_cast<const RelocationSection>(relocation_section);
  252. }
  253. const Image::Section Image::lookup_section(const String& name) const
  254. {
  255. ASSERT(m_valid);
  256. if (auto it = m_sections.find(name); it != m_sections.end())
  257. return section((*it).value);
  258. return section(0);
  259. }
  260. StringView Image::Symbol::raw_data() const
  261. {
  262. auto& section = this->section();
  263. return { section.raw_data() + (value() - section.address()), size() };
  264. }
  265. Optional<Image::Symbol> Image::find_demangled_function(const String& name) const
  266. {
  267. Optional<Image::Symbol> found;
  268. for_each_symbol([&](const Image::Symbol symbol) {
  269. if (symbol.type() != STT_FUNC)
  270. return IterationDecision::Continue;
  271. auto demangled = demangle(symbol.name());
  272. auto index_of_paren = demangled.index_of("(");
  273. if (index_of_paren.has_value()) {
  274. demangled = demangled.substring(0, index_of_paren.value());
  275. }
  276. if (demangled != name)
  277. return IterationDecision::Continue;
  278. found = symbol;
  279. return IterationDecision::Break;
  280. });
  281. return found;
  282. }
  283. } // end namespace ELF