Image.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/BinarySearch.h>
  7. #include <AK/Debug.h>
  8. #include <AK/Demangle.h>
  9. #include <AK/Memory.h>
  10. #include <AK/QuickSort.h>
  11. #include <AK/StringBuilder.h>
  12. #include <AK/StringView.h>
  13. #include <LibELF/Image.h>
  14. #include <LibELF/Validation.h>
  15. #include <limits.h>
  16. namespace ELF {
  17. Image::Image(ReadonlyBytes bytes, bool verbose_logging)
  18. : m_buffer(bytes.data())
  19. , m_size(bytes.size())
  20. , m_verbose_logging(verbose_logging)
  21. {
  22. parse();
  23. }
  24. Image::Image(const u8* buffer, size_t size, bool verbose_logging)
  25. : Image(ReadonlyBytes { buffer, size }, verbose_logging)
  26. {
  27. }
  28. Image::~Image()
  29. {
  30. }
  31. #if ELF_IMAGE_DEBUG
  32. static const char* object_file_type_to_string(ElfW(Half) type)
  33. {
  34. switch (type) {
  35. case ET_NONE:
  36. return "None";
  37. case ET_REL:
  38. return "Relocatable";
  39. case ET_EXEC:
  40. return "Executable";
  41. case ET_DYN:
  42. return "Shared object";
  43. case ET_CORE:
  44. return "Core";
  45. default:
  46. return "(?)";
  47. }
  48. }
  49. #endif
  50. StringView Image::section_index_to_string(unsigned index) const
  51. {
  52. VERIFY(m_valid);
  53. if (index == SHN_UNDEF)
  54. return "Undefined"sv;
  55. if (index >= SHN_LORESERVE)
  56. return "Reserved"sv;
  57. return section(index).name();
  58. }
  59. unsigned Image::symbol_count() const
  60. {
  61. VERIFY(m_valid);
  62. if (!section_count())
  63. return 0;
  64. return section(m_symbol_table_section_index).entry_count();
  65. }
  66. void Image::dump() const
  67. {
  68. #if ELF_IMAGE_DEBUG
  69. dbgln("ELF::Image({:p}) {{", this);
  70. dbgln(" is_valid: {}", is_valid());
  71. if (!is_valid()) {
  72. dbgln("}}");
  73. return;
  74. }
  75. dbgln(" type: {}", object_file_type_to_string(header().e_type));
  76. dbgln(" machine: {}", header().e_machine);
  77. dbgln(" entry: {:x}", header().e_entry);
  78. dbgln(" shoff: {}", header().e_shoff);
  79. dbgln(" shnum: {}", header().e_shnum);
  80. dbgln(" phoff: {}", header().e_phoff);
  81. dbgln(" phnum: {}", header().e_phnum);
  82. dbgln(" shstrndx: {}", header().e_shstrndx);
  83. for_each_program_header([&](const ProgramHeader& program_header) {
  84. dbgln(" Program Header {}: {{", program_header.index());
  85. dbgln(" type: {:x}", program_header.type());
  86. dbgln(" offset: {:x}", program_header.offset());
  87. dbgln(" flags: {:x}", program_header.flags());
  88. dbgln(" }}");
  89. });
  90. for (unsigned i = 0; i < header().e_shnum; ++i) {
  91. const auto& section = this->section(i);
  92. dbgln(" Section {}: {{", i);
  93. dbgln(" name: {}", section.name());
  94. dbgln(" type: {:x}", section.type());
  95. dbgln(" offset: {:x}", section.offset());
  96. dbgln(" size: {}", section.size());
  97. dbgln(" ");
  98. dbgln(" }}");
  99. }
  100. dbgln("Symbol count: {} (table is {})", symbol_count(), m_symbol_table_section_index);
  101. for (unsigned i = 1; i < symbol_count(); ++i) {
  102. const auto& sym = symbol(i);
  103. dbgln("Symbol @{}:", i);
  104. dbgln(" Name: {}", sym.name());
  105. dbgln(" In section: {}", section_index_to_string(sym.section_index()));
  106. dbgln(" Value: {}", sym.value());
  107. dbgln(" Size: {}", sym.size());
  108. }
  109. dbgln("}}");
  110. #endif
  111. }
  112. unsigned Image::section_count() const
  113. {
  114. VERIFY(m_valid);
  115. return header().e_shnum;
  116. }
  117. unsigned Image::program_header_count() const
  118. {
  119. VERIFY(m_valid);
  120. return header().e_phnum;
  121. }
  122. bool Image::parse()
  123. {
  124. if (m_size < sizeof(ElfW(Ehdr)) || !validate_elf_header(header(), m_size, m_verbose_logging)) {
  125. if (m_verbose_logging)
  126. dbgln("ELF::Image::parse(): ELF Header not valid");
  127. m_valid = false;
  128. return false;
  129. }
  130. if (!validate_program_headers(header(), m_size, m_buffer, m_size, nullptr, m_verbose_logging)) {
  131. if (m_verbose_logging)
  132. dbgln("ELF::Image::parse(): ELF Program Headers not valid");
  133. m_valid = false;
  134. return false;
  135. }
  136. m_valid = true;
  137. // First locate the string tables.
  138. for (unsigned i = 0; i < section_count(); ++i) {
  139. auto& sh = section_header(i);
  140. if (sh.sh_type == SHT_SYMTAB) {
  141. if (m_symbol_table_section_index && m_symbol_table_section_index != i) {
  142. m_valid = false;
  143. return false;
  144. }
  145. m_symbol_table_section_index = i;
  146. }
  147. if (sh.sh_type == SHT_STRTAB && i != header().e_shstrndx) {
  148. if (section_header_table_string(sh.sh_name) == ELF_STRTAB)
  149. m_string_table_section_index = i;
  150. }
  151. }
  152. return m_valid;
  153. }
  154. StringView Image::table_string(unsigned table_index, unsigned offset) const
  155. {
  156. VERIFY(m_valid);
  157. auto& sh = section_header(table_index);
  158. if (sh.sh_type != SHT_STRTAB)
  159. return nullptr;
  160. size_t computed_offset = sh.sh_offset + offset;
  161. if (computed_offset >= m_size) {
  162. if (m_verbose_logging)
  163. dbgln("SHENANIGANS! Image::table_string() computed offset outside image.");
  164. return {};
  165. }
  166. size_t max_length = min(m_size - computed_offset, (size_t)PAGE_SIZE);
  167. size_t length = strnlen(raw_data(sh.sh_offset + offset), max_length);
  168. return { raw_data(sh.sh_offset + offset), length };
  169. }
  170. StringView Image::section_header_table_string(unsigned offset) const
  171. {
  172. VERIFY(m_valid);
  173. return table_string(header().e_shstrndx, offset);
  174. }
  175. StringView Image::table_string(unsigned offset) const
  176. {
  177. VERIFY(m_valid);
  178. return table_string(m_string_table_section_index, offset);
  179. }
  180. const char* Image::raw_data(unsigned offset) const
  181. {
  182. VERIFY(offset < m_size); // Callers must check indices into raw_data()'s result are also in bounds.
  183. return reinterpret_cast<const char*>(m_buffer) + offset;
  184. }
  185. const ElfW(Ehdr) & Image::header() const
  186. {
  187. VERIFY(m_size >= sizeof(ElfW(Ehdr)));
  188. return *reinterpret_cast<const ElfW(Ehdr)*>(raw_data(0));
  189. }
  190. const ElfW(Phdr) & Image::program_header_internal(unsigned index) const
  191. {
  192. VERIFY(m_valid);
  193. VERIFY(index < header().e_phnum);
  194. return *reinterpret_cast<const ElfW(Phdr)*>(raw_data(header().e_phoff + (index * sizeof(ElfW(Phdr)))));
  195. }
  196. const ElfW(Shdr) & Image::section_header(unsigned index) const
  197. {
  198. VERIFY(m_valid);
  199. VERIFY(index < header().e_shnum);
  200. return *reinterpret_cast<const ElfW(Shdr)*>(raw_data(header().e_shoff + (index * header().e_shentsize)));
  201. }
  202. Image::Symbol Image::symbol(unsigned index) const
  203. {
  204. VERIFY(m_valid);
  205. VERIFY(index < symbol_count());
  206. auto* raw_syms = reinterpret_cast<const ElfW(Sym)*>(raw_data(section(m_symbol_table_section_index).offset()));
  207. return Symbol(*this, index, raw_syms[index]);
  208. }
  209. Image::Section Image::section(unsigned index) const
  210. {
  211. VERIFY(m_valid);
  212. VERIFY(index < section_count());
  213. return Section(*this, index);
  214. }
  215. Image::ProgramHeader Image::program_header(unsigned index) const
  216. {
  217. VERIFY(m_valid);
  218. VERIFY(index < program_header_count());
  219. return ProgramHeader(*this, index);
  220. }
  221. Image::Relocation Image::RelocationSection::relocation(unsigned index) const
  222. {
  223. VERIFY(index < relocation_count());
  224. auto* rels = reinterpret_cast<const ElfW(Rel)*>(m_image.raw_data(offset()));
  225. return Relocation(m_image, rels[index]);
  226. }
  227. Optional<Image::RelocationSection> Image::Section::relocations() const
  228. {
  229. StringBuilder builder;
  230. builder.append(".rel"sv);
  231. builder.append(name());
  232. auto relocation_section = m_image.lookup_section(builder.to_string());
  233. if (!relocation_section.has_value())
  234. return {};
  235. dbgln_if(ELF_IMAGE_DEBUG, "Found relocations for {} in {}", name(), relocation_section.value().name());
  236. return static_cast<RelocationSection>(relocation_section.value());
  237. }
  238. Optional<Image::Section> Image::lookup_section(const StringView& name) const
  239. {
  240. VERIFY(m_valid);
  241. for (unsigned i = 0; i < section_count(); ++i) {
  242. auto section = this->section(i);
  243. if (section.name() == name)
  244. return section;
  245. }
  246. return {};
  247. }
  248. StringView Image::Symbol::raw_data() const
  249. {
  250. auto section = this->section();
  251. return { section.raw_data() + (value() - section.address()), size() };
  252. }
  253. #ifndef KERNEL
  254. Optional<Image::Symbol> Image::find_demangled_function(const StringView& name) const
  255. {
  256. Optional<Image::Symbol> found;
  257. for_each_symbol([&](const Image::Symbol& symbol) {
  258. if (symbol.type() != STT_FUNC)
  259. return IterationDecision::Continue;
  260. if (symbol.is_undefined())
  261. return IterationDecision::Continue;
  262. auto demangled = demangle(symbol.name());
  263. auto index_of_paren = demangled.find('(');
  264. if (index_of_paren.has_value()) {
  265. demangled = demangled.substring(0, index_of_paren.value());
  266. }
  267. if (demangled != name)
  268. return IterationDecision::Continue;
  269. found = symbol;
  270. return IterationDecision::Break;
  271. });
  272. return found;
  273. }
  274. #endif
  275. Image::SortedSymbol* Image::find_sorted_symbol(FlatPtr address) const
  276. {
  277. if (m_sorted_symbols.is_empty())
  278. sort_symbols();
  279. size_t index = 0;
  280. binary_search(m_sorted_symbols, nullptr, &index, [&address](auto, auto& candidate) {
  281. if (address < candidate.address)
  282. return -1;
  283. else if (address > candidate.address)
  284. return 1;
  285. else
  286. return 0;
  287. });
  288. // FIXME: The error path here feels strange, index == 0 means error but what about symbol #0?
  289. if (index == 0)
  290. return nullptr;
  291. return &m_sorted_symbols[index];
  292. }
  293. Optional<Image::Symbol> Image::find_symbol(FlatPtr address, u32* out_offset) const
  294. {
  295. auto symbol_count = this->symbol_count();
  296. if (!symbol_count)
  297. return {};
  298. auto* symbol = find_sorted_symbol(address);
  299. if (!symbol)
  300. return {};
  301. if (out_offset)
  302. *out_offset = address - symbol->address;
  303. return symbol->symbol;
  304. }
  305. NEVER_INLINE void Image::sort_symbols() const
  306. {
  307. m_sorted_symbols.ensure_capacity(symbol_count());
  308. for_each_symbol([this](const auto& symbol) {
  309. m_sorted_symbols.append({ symbol.value(), symbol.name(), {}, symbol });
  310. });
  311. quick_sort(m_sorted_symbols, [](auto& a, auto& b) {
  312. return a.address < b.address;
  313. });
  314. }
  315. #ifndef KERNEL
  316. String Image::symbolicate(FlatPtr address, u32* out_offset) const
  317. {
  318. auto symbol_count = this->symbol_count();
  319. if (!symbol_count) {
  320. if (out_offset)
  321. *out_offset = 0;
  322. return "??";
  323. }
  324. auto* symbol = find_sorted_symbol(address);
  325. if (!symbol) {
  326. if (out_offset)
  327. *out_offset = 0;
  328. return "??";
  329. }
  330. auto& demangled_name = symbol->demangled_name;
  331. if (demangled_name.is_null())
  332. demangled_name = demangle(symbol->name);
  333. if (out_offset) {
  334. *out_offset = address - symbol->address;
  335. return demangled_name;
  336. }
  337. return String::formatted("{} +{:#x}", demangled_name, address - symbol->address);
  338. }
  339. #endif
  340. } // end namespace ELF