DWARFAbbreviationDeclaration.cpp 7.8 KB

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