DwarfInfo.cpp 15 KB

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