DwarfInfo.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  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 = TRY(LineProgram::create(*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::RefUData: {
  146. auto data = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  147. value.m_type = AttributeValue::Type::DieReference;
  148. VERIFY(unit);
  149. value.m_data.as_unsigned = data + unit->offset();
  150. break;
  151. }
  152. case AttributeDataForm::FlagPresent: {
  153. value.m_type = AttributeValue::Type::Boolean;
  154. value.m_data.as_bool = true;
  155. break;
  156. }
  157. case AttributeDataForm::ExprLoc: {
  158. size_t length = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  159. value.m_type = AttributeValue::Type::DwarfExpression;
  160. TRY(assign_raw_bytes_value(length));
  161. break;
  162. }
  163. case AttributeDataForm::String: {
  164. u32 str_offset = TRY(debug_info_stream.tell());
  165. value.m_type = AttributeValue::Type::String;
  166. value.m_data.as_string = bit_cast<char const*>(debug_info_data().offset_pointer(str_offset));
  167. TRY(debug_info_stream.discard(strlen(value.m_data.as_string) + 1));
  168. break;
  169. }
  170. case AttributeDataForm::Block1: {
  171. value.m_type = AttributeValue::Type::RawBytes;
  172. auto length = TRY(debug_info_stream.read_value<u8>());
  173. TRY(assign_raw_bytes_value(length));
  174. break;
  175. }
  176. case AttributeDataForm::Block2: {
  177. value.m_type = AttributeValue::Type::RawBytes;
  178. auto length = TRY(debug_info_stream.read_value<u16>());
  179. TRY(assign_raw_bytes_value(length));
  180. break;
  181. }
  182. case AttributeDataForm::Block4: {
  183. value.m_type = AttributeValue::Type::RawBytes;
  184. auto length = TRY(debug_info_stream.read_value<u32>());
  185. TRY(assign_raw_bytes_value(length));
  186. break;
  187. }
  188. case AttributeDataForm::Block: {
  189. value.m_type = AttributeValue::Type::RawBytes;
  190. size_t length = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  191. TRY(assign_raw_bytes_value(length));
  192. break;
  193. }
  194. case AttributeDataForm::LineStrP: {
  195. auto offset = TRY(debug_info_stream.read_value<u32>());
  196. value.m_type = AttributeValue::Type::String;
  197. auto strings_data = debug_line_strings_data();
  198. value.m_data.as_string = bit_cast<char const*>(strings_data.offset_pointer(offset));
  199. break;
  200. }
  201. case AttributeDataForm::ImplicitConst: {
  202. /* Value is part of the abbreviation record. */
  203. value.m_type = AttributeValue::Type::SignedNumber;
  204. value.m_data.as_signed = implicit_const_value;
  205. break;
  206. }
  207. case AttributeDataForm::StrX1: {
  208. auto index = TRY(debug_info_stream.read_value<u8>());
  209. value.m_type = AttributeValue::Type::String;
  210. value.m_data.as_unsigned = index;
  211. break;
  212. }
  213. case AttributeDataForm::StrX2: {
  214. auto index = TRY(debug_info_stream.read_value<u16>());
  215. value.m_type = AttributeValue::Type::String;
  216. value.m_data.as_unsigned = index;
  217. break;
  218. }
  219. case AttributeDataForm::StrX4: {
  220. auto index = TRY(debug_info_stream.read_value<u32>());
  221. value.m_type = AttributeValue::Type::String;
  222. value.m_data.as_unsigned = index;
  223. break;
  224. }
  225. case AttributeDataForm::StrX: {
  226. size_t index = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  227. value.m_type = AttributeValue::Type::String;
  228. value.m_data.as_unsigned = index;
  229. break;
  230. }
  231. case AttributeDataForm::AddrX1: {
  232. auto index = TRY(debug_info_stream.read_value<u8>());
  233. value.m_type = AttributeValue::Type::Address;
  234. value.m_data.as_unsigned = index;
  235. break;
  236. }
  237. case AttributeDataForm::AddrX2: {
  238. auto index = TRY(debug_info_stream.read_value<u16>());
  239. value.m_type = AttributeValue::Type::Address;
  240. value.m_data.as_unsigned = index;
  241. break;
  242. }
  243. case AttributeDataForm::AddrX4: {
  244. auto index = TRY(debug_info_stream.read_value<u32>());
  245. value.m_type = AttributeValue::Type::Address;
  246. value.m_data.as_unsigned = index;
  247. break;
  248. }
  249. case AttributeDataForm::AddrX: {
  250. size_t index = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  251. value.m_type = AttributeValue::Type::Address;
  252. value.m_data.as_unsigned = index;
  253. break;
  254. }
  255. case AttributeDataForm::LocListX:
  256. case AttributeDataForm::RngListX: {
  257. size_t index = TRY(debug_info_stream.read_value<LEB128<size_t>>());
  258. value.m_type = AttributeValue::Type::UnsignedNumber;
  259. value.m_data.as_unsigned = index;
  260. break;
  261. }
  262. default:
  263. dbgln("Unimplemented AttributeDataForm: {}", to_underlying(form));
  264. VERIFY_NOT_REACHED();
  265. }
  266. return value;
  267. }
  268. ErrorOr<void> DwarfInfo::build_cached_dies() const
  269. {
  270. auto insert_to_cache = [this](DIE const& die, DIERange const& range) {
  271. m_cached_dies_by_range.insert(range.start_address, DIEAndRange { die, range });
  272. m_cached_dies_by_offset.insert(die.offset(), die);
  273. };
  274. auto get_ranges_of_die = [this](DIE const& die) -> ErrorOr<Vector<DIERange>> {
  275. auto ranges = TRY(die.get_attribute(Attribute::Ranges));
  276. if (ranges.has_value()) {
  277. size_t offset;
  278. if (ranges->form() == AttributeDataForm::SecOffset) {
  279. offset = ranges->as_unsigned();
  280. } else {
  281. auto index = ranges->as_unsigned();
  282. auto base = TRY(die.compilation_unit().range_lists_base());
  283. // FIXME: This assumes that the format is DWARf32
  284. auto offsets = debug_range_lists_data().slice(base);
  285. offset = ByteReader::load32(offsets.offset_pointer(index * sizeof(u32))) + base;
  286. }
  287. Vector<DIERange> entries;
  288. if (die.compilation_unit().dwarf_version() == 5) {
  289. auto range_lists_stream = TRY(try_make<FixedMemoryStream>(debug_range_lists_data()));
  290. TRY(range_lists_stream->seek(offset));
  291. AddressRangesV5 address_ranges(move(range_lists_stream), die.compilation_unit());
  292. TRY(address_ranges.for_each_range([&entries](auto range) {
  293. entries.empend(range.start, range.end);
  294. }));
  295. } else {
  296. auto ranges_stream = TRY(try_make<FixedMemoryStream>(debug_ranges_data()));
  297. TRY(ranges_stream->seek(offset));
  298. AddressRangesV4 address_ranges(move(ranges_stream), die.compilation_unit());
  299. TRY(address_ranges.for_each_range([&entries](auto range) {
  300. entries.empend(range.start, range.end);
  301. }));
  302. }
  303. return entries;
  304. }
  305. auto start = TRY(die.get_attribute(Attribute::LowPc));
  306. auto end = TRY(die.get_attribute(Attribute::HighPc));
  307. if (!start.has_value() || !end.has_value())
  308. return Vector<DIERange> {};
  309. VERIFY(start->type() == Dwarf::AttributeValue::Type::Address);
  310. // DW_AT_high_pc attribute can have different meanings depending on the attribute form.
  311. // (Dwarf version 5, section 2.17.2).
  312. uint32_t range_end = 0;
  313. if (end->form() == Dwarf::AttributeDataForm::Addr)
  314. range_end = TRY(end->as_addr());
  315. else
  316. range_end = TRY(start->as_addr()) + end->as_unsigned();
  317. return Vector<DIERange> { DIERange { TRY(start.value().as_addr()), range_end } };
  318. };
  319. // If we simply use a lambda, type deduction fails because it's used recursively.
  320. Function<ErrorOr<void>(DIE const& die)> insert_to_cache_recursively;
  321. insert_to_cache_recursively = [&](DIE const& die) -> ErrorOr<void> {
  322. if (die.offset() == 0 || die.parent_offset().has_value()) {
  323. auto ranges = TRY(get_ranges_of_die(die));
  324. for (auto& range : ranges) {
  325. insert_to_cache(die, range);
  326. }
  327. }
  328. TRY(die.for_each_child([&](DIE const& child) -> ErrorOr<void> {
  329. if (!child.is_null()) {
  330. TRY(insert_to_cache_recursively(child));
  331. }
  332. return {};
  333. }));
  334. return {};
  335. };
  336. TRY(for_each_compilation_unit([&](CompilationUnit const& compilation_unit) -> ErrorOr<void> {
  337. TRY(insert_to_cache_recursively(compilation_unit.root_die()));
  338. return {};
  339. }));
  340. m_built_cached_dies = true;
  341. return {};
  342. }
  343. ErrorOr<Optional<DIE>> DwarfInfo::get_die_at_address(FlatPtr address) const
  344. {
  345. if (!m_built_cached_dies)
  346. TRY(build_cached_dies());
  347. auto iter = m_cached_dies_by_range.find_largest_not_above_iterator(address);
  348. while (!iter.is_end() && !iter.is_begin() && iter->range.end_address < address) {
  349. --iter;
  350. }
  351. if (iter.is_end())
  352. return Optional<DIE> {};
  353. if (iter->range.start_address > address || iter->range.end_address < address) {
  354. return Optional<DIE> {};
  355. }
  356. return iter->die;
  357. }
  358. ErrorOr<Optional<DIE>> DwarfInfo::get_cached_die_at_offset(FlatPtr offset) const
  359. {
  360. if (!m_built_cached_dies)
  361. TRY(build_cached_dies());
  362. auto* die = m_cached_dies_by_offset.find(offset);
  363. if (!die)
  364. return Optional<DIE> {};
  365. return *die;
  366. }
  367. }