DWARFAbbreviationDeclaration.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. //===- DWARFAbbreviationDeclaration.cpp -----------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
  9. #include "llvm/BinaryFormat/Dwarf.h"
  10. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  11. #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  13. #include "llvm/Support/DataExtractor.h"
  14. #include "llvm/Support/FormatVariadic.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. #include <cstddef>
  17. #include <cstdint>
  18. using namespace llvm;
  19. using namespace dwarf;
  20. void DWARFAbbreviationDeclaration::clear() {
  21. Code = 0;
  22. Tag = DW_TAG_null;
  23. CodeByteSize = 0;
  24. HasChildren = false;
  25. AttributeSpecs.clear();
  26. FixedAttributeSize.reset();
  27. }
  28. DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
  29. clear();
  30. }
  31. bool
  32. DWARFAbbreviationDeclaration::extract(DataExtractor Data,
  33. uint64_t* OffsetPtr) {
  34. clear();
  35. const uint64_t Offset = *OffsetPtr;
  36. Code = Data.getULEB128(OffsetPtr);
  37. if (Code == 0) {
  38. return false;
  39. }
  40. CodeByteSize = *OffsetPtr - Offset;
  41. Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
  42. if (Tag == DW_TAG_null) {
  43. clear();
  44. return false;
  45. }
  46. uint8_t ChildrenByte = Data.getU8(OffsetPtr);
  47. HasChildren = (ChildrenByte == DW_CHILDREN_yes);
  48. // Assign a value to our optional FixedAttributeSize member variable. If
  49. // this member variable still has a value after the while loop below, then
  50. // all attribute data in this abbreviation declaration has a fixed byte size.
  51. FixedAttributeSize = FixedSizeInfo();
  52. // Read all of the abbreviation attributes and forms.
  53. while (true) {
  54. auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
  55. auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
  56. if (A && F) {
  57. bool IsImplicitConst = (F == DW_FORM_implicit_const);
  58. if (IsImplicitConst) {
  59. int64_t V = Data.getSLEB128(OffsetPtr);
  60. AttributeSpecs.push_back(AttributeSpec(A, F, V));
  61. continue;
  62. }
  63. std::optional<uint8_t> ByteSize;
  64. // If this abbrevation still has a fixed byte size, then update the
  65. // FixedAttributeSize as needed.
  66. switch (F) {
  67. case DW_FORM_addr:
  68. if (FixedAttributeSize)
  69. ++FixedAttributeSize->NumAddrs;
  70. break;
  71. case DW_FORM_ref_addr:
  72. if (FixedAttributeSize)
  73. ++FixedAttributeSize->NumRefAddrs;
  74. break;
  75. case DW_FORM_strp:
  76. case DW_FORM_GNU_ref_alt:
  77. case DW_FORM_GNU_strp_alt:
  78. case DW_FORM_line_strp:
  79. case DW_FORM_sec_offset:
  80. case DW_FORM_strp_sup:
  81. if (FixedAttributeSize)
  82. ++FixedAttributeSize->NumDwarfOffsets;
  83. break;
  84. default:
  85. // The form has a byte size that doesn't depend on Params.
  86. // If it's a fixed size, keep track of it.
  87. if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
  88. if (FixedAttributeSize)
  89. FixedAttributeSize->NumBytes += *ByteSize;
  90. break;
  91. }
  92. // Indicate we no longer have a fixed byte size for this
  93. // abbreviation by clearing the FixedAttributeSize optional value
  94. // so it doesn't have a value.
  95. FixedAttributeSize.reset();
  96. break;
  97. }
  98. // Record this attribute and its fixed size if it has one.
  99. AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
  100. } else if (A == 0 && F == 0) {
  101. // We successfully reached the end of this abbreviation declaration
  102. // since both attribute and form are zero.
  103. break;
  104. } else {
  105. // Attribute and form pairs must either both be non-zero, in which case
  106. // they are added to the abbreviation declaration, or both be zero to
  107. // terminate the abbrevation declaration. In this case only one was
  108. // zero which is an error.
  109. clear();
  110. return false;
  111. }
  112. }
  113. return true;
  114. }
  115. void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
  116. OS << '[' << getCode() << "] ";
  117. OS << formatv("{0}", getTag());
  118. OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
  119. for (const AttributeSpec &Spec : AttributeSpecs) {
  120. OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
  121. if (Spec.isImplicitConst())
  122. OS << '\t' << Spec.getImplicitConstValue();
  123. OS << '\n';
  124. }
  125. OS << '\n';
  126. }
  127. std::optional<uint32_t>
  128. DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
  129. for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
  130. if (AttributeSpecs[i].Attr == Attr)
  131. return i;
  132. }
  133. return std::nullopt;
  134. }
  135. uint64_t DWARFAbbreviationDeclaration::getAttributeOffsetFromIndex(
  136. uint32_t AttrIndex, uint64_t DIEOffset, const DWARFUnit &U) const {
  137. DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
  138. // Add the byte size of ULEB that for the abbrev Code so we can start
  139. // skipping the attribute data.
  140. uint64_t Offset = DIEOffset + CodeByteSize;
  141. for (uint32_t CurAttrIdx = 0; CurAttrIdx != AttrIndex; ++CurAttrIdx)
  142. // Match Offset along until we get to the attribute we want.
  143. if (auto FixedSize = AttributeSpecs[CurAttrIdx].getByteSize(U))
  144. Offset += *FixedSize;
  145. else
  146. DWARFFormValue::skipValue(AttributeSpecs[CurAttrIdx].Form, DebugInfoData,
  147. &Offset, U.getFormParams());
  148. return Offset;
  149. }
  150. std::optional<DWARFFormValue>
  151. DWARFAbbreviationDeclaration::getAttributeValueFromOffset(
  152. uint32_t AttrIndex, uint64_t Offset, const DWARFUnit &U) const {
  153. assert(AttributeSpecs.size() > AttrIndex &&
  154. "Attribute Index is out of bounds.");
  155. // We have arrived at the attribute to extract, extract if from Offset.
  156. const AttributeSpec &Spec = AttributeSpecs[AttrIndex];
  157. if (Spec.isImplicitConst())
  158. return DWARFFormValue::createFromSValue(Spec.Form,
  159. Spec.getImplicitConstValue());
  160. DWARFFormValue FormValue(Spec.Form);
  161. DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
  162. if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
  163. return FormValue;
  164. return std::nullopt;
  165. }
  166. std::optional<DWARFFormValue>
  167. DWARFAbbreviationDeclaration::getAttributeValue(const uint64_t DIEOffset,
  168. const dwarf::Attribute Attr,
  169. const DWARFUnit &U) const {
  170. // Check if this abbreviation has this attribute without needing to skip
  171. // any data so we can return quickly if it doesn't.
  172. std::optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
  173. if (!MatchAttrIndex)
  174. return std::nullopt;
  175. uint64_t Offset = getAttributeOffsetFromIndex(*MatchAttrIndex, DIEOffset, U);
  176. return getAttributeValueFromOffset(*MatchAttrIndex, Offset, U);
  177. }
  178. size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
  179. const DWARFUnit &U) const {
  180. size_t ByteSize = NumBytes;
  181. if (NumAddrs)
  182. ByteSize += NumAddrs * U.getAddressByteSize();
  183. if (NumRefAddrs)
  184. ByteSize += NumRefAddrs * U.getRefAddrByteSize();
  185. if (NumDwarfOffsets)
  186. ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
  187. return ByteSize;
  188. }
  189. std::optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
  190. const DWARFUnit &U) const {
  191. if (isImplicitConst())
  192. return 0;
  193. if (ByteSize.HasByteSize)
  194. return ByteSize.ByteSize;
  195. std::optional<int64_t> S;
  196. auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
  197. if (FixedByteSize)
  198. S = *FixedByteSize;
  199. return S;
  200. }
  201. std::optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
  202. const DWARFUnit &U) const {
  203. if (FixedAttributeSize)
  204. return FixedAttributeSize->getByteSize(U);
  205. return std::nullopt;
  206. }