DwarfInfo.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. * Copyright (c) 2020-2021, Itamar S. <itamar8910@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "DwarfInfo.h"
  7. #include "AddressRanges.h"
  8. #include "AttributeValue.h"
  9. #include "CompilationUnit.h"
  10. #include <AK/ByteReader.h>
  11. #include <AK/LEB128.h>
  12. #include <AK/MemoryStream.h>
  13. #include <LibDebug/DebugInfo.h>
  14. namespace Debug::Dwarf {
  15. DwarfInfo::DwarfInfo(ELF::Image const& elf)
  16. : m_elf(elf)
  17. {
  18. m_debug_info_data = section_data(".debug_info"sv);
  19. m_abbreviation_data = section_data(".debug_abbrev"sv);
  20. m_debug_strings_data = section_data(".debug_str"sv);
  21. m_debug_line_data = section_data(".debug_line"sv);
  22. m_debug_line_strings_data = section_data(".debug_line_str"sv);
  23. m_debug_range_lists_data = section_data(".debug_rnglists"sv);
  24. m_debug_str_offsets_data = section_data(".debug_str_offsets"sv);
  25. m_debug_addr_data = section_data(".debug_addr"sv);
  26. m_debug_ranges_data = section_data(".debug_ranges"sv);
  27. populate_compilation_units().release_value_but_fixme_should_propagate_errors();
  28. }
  29. DwarfInfo::~DwarfInfo() = default;
  30. ReadonlyBytes DwarfInfo::section_data(StringView section_name) const
  31. {
  32. auto section = m_elf.lookup_section(section_name);
  33. if (!section.has_value())
  34. return {};
  35. return section->bytes();
  36. }
  37. ErrorOr<void> DwarfInfo::populate_compilation_units()
  38. {
  39. if (!m_debug_info_data.data())
  40. return {};
  41. FixedMemoryStream debug_info_stream { m_debug_info_data };
  42. FixedMemoryStream line_info_stream { m_debug_line_data };
  43. while (!debug_info_stream.is_eof()) {
  44. auto unit_offset = TRY(debug_info_stream.tell());
  45. auto compilation_unit_header = TRY(debug_info_stream.read_value<CompilationUnitHeader>());
  46. VERIFY(compilation_unit_header.common.version <= 5);
  47. VERIFY(compilation_unit_header.address_size() == sizeof(FlatPtr));
  48. u32 length_after_header = compilation_unit_header.length() - (compilation_unit_header.header_size() - offsetof(CompilationUnitHeader, common.version));
  49. auto line_program = make<LineProgram>(*this, line_info_stream);
  50. // HACK: Clang generates line programs for embedded resource assembly files, but not compile units.
  51. // Meaning that for graphical applications, some line info data would be unread, triggering the assertion below.
  52. // As a fix, we don't create compilation units for line programs that come from resource files.
  53. #if defined(AK_COMPILER_CLANG)
  54. if (line_program->looks_like_embedded_resource()) {
  55. TRY(debug_info_stream.seek(unit_offset));
  56. } else
  57. #endif
  58. {
  59. m_compilation_units.append(make<CompilationUnit>(*this, unit_offset, compilation_unit_header, move(line_program)));
  60. TRY(debug_info_stream.discard(length_after_header));
  61. }
  62. }
  63. VERIFY(line_info_stream.is_eof());
  64. return {};
  65. }
  66. ErrorOr<AttributeValue> DwarfInfo::get_attribute_value(AttributeDataForm form, ssize_t implicit_const_value,
  67. SeekableStream& debug_info_stream, CompilationUnit const* unit) const
  68. {
  69. AttributeValue value;
  70. value.m_form = form;
  71. value.m_compilation_unit = unit;
  72. auto assign_raw_bytes_value = [&](size_t length) -> ErrorOr<void> {
  73. value.m_data.as_raw_bytes = { debug_info_data().offset_pointer(TRY(debug_info_stream.tell())), length };
  74. TRY(debug_info_stream.discard(length));
  75. return {};
  76. };
  77. switch (form) {
  78. case AttributeDataForm::StringPointer: {
  79. auto offset = TRY(debug_info_stream.read_value<u32>());
  80. value.m_type = AttributeValue::Type::String;
  81. auto strings_data = debug_strings_data();
  82. value.m_data.as_string = bit_cast<char const*>(strings_data.offset_pointer(offset));
  83. break;
  84. }
  85. case AttributeDataForm::Data1: {
  86. auto data = TRY(debug_info_stream.read_value<u8>());
  87. value.m_type = AttributeValue::Type::UnsignedNumber;
  88. value.m_data.as_unsigned = data;
  89. break;
  90. }
  91. case AttributeDataForm::Data2: {
  92. auto data = TRY(debug_info_stream.read_value<u16>());
  93. value.m_type = AttributeValue::Type::UnsignedNumber;
  94. value.m_data.as_signed = data;
  95. break;
  96. }
  97. case AttributeDataForm::Addr: {
  98. auto address = TRY(debug_info_stream.read_value<FlatPtr>());
  99. value.m_type = AttributeValue::Type::Address;
  100. value.m_data.as_addr = address;
  101. break;
  102. }
  103. case AttributeDataForm::SData: {
  104. i64 data = TRY(debug_info_stream.read_value<LEB128<i64>>());
  105. value.m_type = AttributeValue::Type::SignedNumber;
  106. value.m_data.as_signed = data;
  107. break;
  108. }
  109. case AttributeDataForm::UData: {
  110. u64 data = TRY(debug_info_stream.read_value<LEB128<u64>>());
  111. value.m_type = AttributeValue::Type::UnsignedNumber;
  112. value.m_data.as_unsigned = data;
  113. break;
  114. }
  115. case AttributeDataForm::SecOffset: {
  116. auto data = TRY(debug_info_stream.read_value<u32>());
  117. value.m_type = AttributeValue::Type::SecOffset;
  118. value.m_data.as_unsigned = data;
  119. break;
  120. }
  121. case AttributeDataForm::Data4: {
  122. auto data = TRY(debug_info_stream.read_value<u32>());
  123. value.m_type = AttributeValue::Type::UnsignedNumber;
  124. value.m_data.as_unsigned = data;
  125. break;
  126. }
  127. case AttributeDataForm::Data8: {
  128. auto data = TRY(debug_info_stream.read_value<u64>());
  129. value.m_type = AttributeValue::Type::UnsignedNumber;
  130. value.m_data.as_unsigned = data;
  131. break;
  132. }
  133. case AttributeDataForm::Data16: {
  134. value.m_type = AttributeValue::Type::RawBytes;
  135. TRY(assign_raw_bytes_value(16));
  136. break;
  137. }
  138. case AttributeDataForm::Ref4: {
  139. auto data = TRY(debug_info_stream.read_value<u32>());
  140. value.m_type = AttributeValue::Type::DieReference;
  141. VERIFY(unit);
  142. value.m_data.as_unsigned = data + unit->offset();
  143. break;
  144. }
  145. case AttributeDataForm::FlagPresent: {
  146. value.m_type = AttributeValue::Type::Boolean;
  147. value.m_data.as_bool = true;
  148. break;
  149. }
  150. case AttributeDataForm::ExprLoc: {
  151. size_t length = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  152. value.m_type = AttributeValue::Type::DwarfExpression;
  153. TRY(assign_raw_bytes_value(length));
  154. break;
  155. }
  156. case AttributeDataForm::String: {
  157. u32 str_offset = TRY(debug_info_stream.tell());
  158. value.m_type = AttributeValue::Type::String;
  159. value.m_data.as_string = bit_cast<char const*>(debug_info_data().offset_pointer(str_offset));
  160. TRY(debug_info_stream.discard(strlen(value.m_data.as_string) + 1));
  161. break;
  162. }
  163. case AttributeDataForm::Block1: {
  164. value.m_type = AttributeValue::Type::RawBytes;
  165. auto length = TRY(debug_info_stream.read_value<u8>());
  166. TRY(assign_raw_bytes_value(length));
  167. break;
  168. }
  169. case AttributeDataForm::Block2: {
  170. value.m_type = AttributeValue::Type::RawBytes;
  171. auto length = TRY(debug_info_stream.read_value<u16>());
  172. TRY(assign_raw_bytes_value(length));
  173. break;
  174. }
  175. case AttributeDataForm::Block4: {
  176. value.m_type = AttributeValue::Type::RawBytes;
  177. auto length = TRY(debug_info_stream.read_value<u32>());
  178. TRY(assign_raw_bytes_value(length));
  179. break;
  180. }
  181. case AttributeDataForm::Block: {
  182. value.m_type = AttributeValue::Type::RawBytes;
  183. size_t length = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  184. TRY(assign_raw_bytes_value(length));
  185. break;
  186. }
  187. case AttributeDataForm::LineStrP: {
  188. auto offset = TRY(debug_info_stream.read_value<u32>());
  189. value.m_type = AttributeValue::Type::String;
  190. auto strings_data = debug_line_strings_data();
  191. value.m_data.as_string = bit_cast<char const*>(strings_data.offset_pointer(offset));
  192. break;
  193. }
  194. case AttributeDataForm::ImplicitConst: {
  195. /* Value is part of the abbreviation record. */
  196. value.m_type = AttributeValue::Type::SignedNumber;
  197. value.m_data.as_signed = implicit_const_value;
  198. break;
  199. }
  200. case AttributeDataForm::StrX1: {
  201. auto index = TRY(debug_info_stream.read_value<u8>());
  202. value.m_type = AttributeValue::Type::String;
  203. value.m_data.as_unsigned = index;
  204. break;
  205. }
  206. case AttributeDataForm::StrX2: {
  207. auto index = TRY(debug_info_stream.read_value<u16>());
  208. value.m_type = AttributeValue::Type::String;
  209. value.m_data.as_unsigned = index;
  210. break;
  211. }
  212. case AttributeDataForm::StrX4: {
  213. auto index = TRY(debug_info_stream.read_value<u32>());
  214. value.m_type = AttributeValue::Type::String;
  215. value.m_data.as_unsigned = index;
  216. break;
  217. }
  218. case AttributeDataForm::StrX: {
  219. size_t index = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  220. value.m_type = AttributeValue::Type::String;
  221. value.m_data.as_unsigned = index;
  222. break;
  223. }
  224. case AttributeDataForm::AddrX1: {
  225. auto index = TRY(debug_info_stream.read_value<u8>());
  226. value.m_type = AttributeValue::Type::Address;
  227. value.m_data.as_unsigned = index;
  228. break;
  229. }
  230. case AttributeDataForm::AddrX2: {
  231. auto index = TRY(debug_info_stream.read_value<u16>());
  232. value.m_type = AttributeValue::Type::Address;
  233. value.m_data.as_unsigned = index;
  234. break;
  235. }
  236. case AttributeDataForm::AddrX4: {
  237. auto index = TRY(debug_info_stream.read_value<u32>());
  238. value.m_type = AttributeValue::Type::Address;
  239. value.m_data.as_unsigned = index;
  240. break;
  241. }
  242. case AttributeDataForm::AddrX: {
  243. size_t index = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  244. value.m_type = AttributeValue::Type::Address;
  245. value.m_data.as_unsigned = index;
  246. break;
  247. }
  248. case AttributeDataForm::RngListX: {
  249. size_t index = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  250. value.m_type = AttributeValue::Type::UnsignedNumber;
  251. value.m_data.as_unsigned = index;
  252. break;
  253. }
  254. default:
  255. dbgln("Unimplemented AttributeDataForm: {}", to_underlying(form));
  256. VERIFY_NOT_REACHED();
  257. }
  258. return value;
  259. }
  260. ErrorOr<void> DwarfInfo::build_cached_dies() const
  261. {
  262. auto insert_to_cache = [this](DIE const& die, DIERange const& range) {
  263. m_cached_dies_by_range.insert(range.start_address, DIEAndRange { die, range });
  264. m_cached_dies_by_offset.insert(die.offset(), die);
  265. };
  266. auto get_ranges_of_die = [this](DIE const& die) -> ErrorOr<Vector<DIERange>> {
  267. auto ranges = TRY(die.get_attribute(Attribute::Ranges));
  268. if (ranges.has_value()) {
  269. size_t offset;
  270. if (ranges->form() == AttributeDataForm::SecOffset) {
  271. offset = ranges->as_unsigned();
  272. } else {
  273. auto index = ranges->as_unsigned();
  274. auto base = TRY(die.compilation_unit().range_lists_base());
  275. // FIXME: This assumes that the format is DWARf32
  276. auto offsets = debug_range_lists_data().slice(base);
  277. offset = ByteReader::load32(offsets.offset_pointer(index * sizeof(u32))) + base;
  278. }
  279. Vector<DIERange> entries;
  280. if (die.compilation_unit().dwarf_version() == 5) {
  281. auto range_lists_stream = TRY(try_make<FixedMemoryStream>(debug_range_lists_data()));
  282. TRY(range_lists_stream->seek(offset));
  283. AddressRangesV5 address_ranges(move(range_lists_stream), die.compilation_unit());
  284. TRY(address_ranges.for_each_range([&entries](auto range) {
  285. entries.empend(range.start, range.end);
  286. }));
  287. } else {
  288. auto ranges_stream = TRY(try_make<FixedMemoryStream>(debug_ranges_data()));
  289. TRY(ranges_stream->seek(offset));
  290. AddressRangesV4 address_ranges(move(ranges_stream), die.compilation_unit());
  291. TRY(address_ranges.for_each_range([&entries](auto range) {
  292. entries.empend(range.start, range.end);
  293. }));
  294. }
  295. return entries;
  296. }
  297. auto start = TRY(die.get_attribute(Attribute::LowPc));
  298. auto end = TRY(die.get_attribute(Attribute::HighPc));
  299. if (!start.has_value() || !end.has_value())
  300. return Vector<DIERange> {};
  301. VERIFY(start->type() == Dwarf::AttributeValue::Type::Address);
  302. // DW_AT_high_pc attribute can have different meanings depending on the attribute form.
  303. // (Dwarf version 5, section 2.17.2).
  304. uint32_t range_end = 0;
  305. if (end->form() == Dwarf::AttributeDataForm::Addr)
  306. range_end = TRY(end->as_addr());
  307. else
  308. range_end = TRY(start->as_addr()) + end->as_unsigned();
  309. return Vector<DIERange> { DIERange { TRY(start.value().as_addr()), range_end } };
  310. };
  311. // If we simply use a lambda, type deduction fails because it's used recursively.
  312. Function<ErrorOr<void>(DIE const& die)> insert_to_cache_recursively;
  313. insert_to_cache_recursively = [&](DIE const& die) -> ErrorOr<void> {
  314. if (die.offset() == 0 || die.parent_offset().has_value()) {
  315. auto ranges = TRY(get_ranges_of_die(die));
  316. for (auto& range : ranges) {
  317. insert_to_cache(die, range);
  318. }
  319. }
  320. TRY(die.for_each_child([&](DIE const& child) -> ErrorOr<void> {
  321. if (!child.is_null()) {
  322. TRY(insert_to_cache_recursively(child));
  323. }
  324. return {};
  325. }));
  326. return {};
  327. };
  328. TRY(for_each_compilation_unit([&](CompilationUnit const& compilation_unit) -> ErrorOr<void> {
  329. TRY(insert_to_cache_recursively(compilation_unit.root_die()));
  330. return {};
  331. }));
  332. m_built_cached_dies = true;
  333. return {};
  334. }
  335. ErrorOr<Optional<DIE>> DwarfInfo::get_die_at_address(FlatPtr address) const
  336. {
  337. if (!m_built_cached_dies)
  338. TRY(build_cached_dies());
  339. auto iter = m_cached_dies_by_range.find_largest_not_above_iterator(address);
  340. while (!iter.is_end() && !iter.is_begin() && iter->range.end_address < address) {
  341. --iter;
  342. }
  343. if (iter.is_end())
  344. return Optional<DIE> {};
  345. if (iter->range.start_address > address || iter->range.end_address < address) {
  346. return Optional<DIE> {};
  347. }
  348. return iter->die;
  349. }
  350. ErrorOr<Optional<DIE>> DwarfInfo::get_cached_die_at_offset(FlatPtr offset) const
  351. {
  352. if (!m_built_cached_dies)
  353. TRY(build_cached_dies());
  354. auto* die = m_cached_dies_by_offset.find(offset);
  355. if (!die)
  356. return Optional<DIE> {};
  357. return *die;
  358. }
  359. }