DwarfInfo.cpp 14 KB

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