172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFAbbreviationDeclaration.h"
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Dwarf.h"
127b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer#include "llvm/Support/Format.h"
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace dwarf;
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
17bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonovvoid DWARFAbbreviationDeclaration::clear() {
18bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  Code = 0;
19bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  Tag = 0;
20bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  HasChildren = false;
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AttributeSpecs.clear();
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
24bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey SamsonovDWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
25bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  clear();
26bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov}
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
28bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonovbool
29bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey SamsonovDWARFAbbreviationDeclaration::extract(DataExtractor Data, uint32_t* OffsetPtr) {
30bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  clear();
31bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  Code = Data.getULEB128(OffsetPtr);
32bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  if (Code == 0) {
33bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    return false;
34bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  }
35bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  Tag = Data.getULEB128(OffsetPtr);
36bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  uint8_t ChildrenByte = Data.getU8(OffsetPtr);
37bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  HasChildren = (ChildrenByte == DW_CHILDREN_yes);
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
39bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  while (true) {
40bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    uint32_t CurOffset = *OffsetPtr;
41bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    uint16_t Attr = Data.getULEB128(OffsetPtr);
42bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    if (CurOffset == *OffsetPtr) {
43bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov      clear();
44bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov      return false;
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
46bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    CurOffset = *OffsetPtr;
47bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    uint16_t Form = Data.getULEB128(OffsetPtr);
48bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    if (CurOffset == *OffsetPtr) {
49bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov      clear();
50bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov      return false;
51bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    }
52bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    if (Attr == 0 && Form == 0)
53bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov      break;
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AttributeSpecs.push_back(AttributeSpec(Attr, Form));
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
57bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  if (Tag == 0) {
58bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    clear();
59bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov    return false;
60bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  }
61bc5e25ddef214e8bebf04bd7abeffade2f21dc4eAlexey Samsonov  return true;
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
6542180e83368b42c4ba4ce01d35e6c97d8b9d3b4bBenjamin Kramer  const char *tagString = TagString(getTag());
667b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer  OS << '[' << getCode() << "] ";
677b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer  if (tagString)
687b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    OS << tagString;
697b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer  else
707b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    OS << format("DW_TAG_Unknown_%x", getTag());
717b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer  OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const AttributeSpec &Spec : AttributeSpecs) {
737b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    OS << '\t';
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *attrString = AttributeString(Spec.Attr);
757b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    if (attrString)
767b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer      OS << attrString;
777b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    else
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("DW_AT_Unknown_%x", Spec.Attr);
797b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    OS << '\t';
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *formString = FormEncodingString(Spec.Form);
817b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    if (formString)
827b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer      OS << formString;
837b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    else
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("DW_FORM_Unknown_%x", Spec.Form);
857b97442b491f0cc69eb0676323b7fe4b14837ac1Benjamin Kramer    OS << '\n';
8642180e83368b42c4ba4ce01d35e6c97d8b9d3b4bBenjamin Kramer  }
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  OS << '\n';
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Krameruint32_t
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFAbbreviationDeclaration::findAttributeIndex(uint16_t attr) const {
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (AttributeSpecs[i].Attr == attr)
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return i;
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return -1U;
9772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
98