DWARFDebugAbbrev.cpp revision 4aa3fea8b13b91800c908f8e7d74fad96adba69a
172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFDebugAbbrev.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 "DWARFDebugAbbrev.h"
1172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/Format.h"
1272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "llvm/Support/raw_ostream.h"
1372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
1472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerbool DWARFAbbreviationDeclarationSet::extract(DataExtractor data,
1672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer                                              uint32_t* offset_ptr) {
1772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const uint32_t beginOffset = *offset_ptr;
1872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Offset = beginOffset;
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  clear();
2072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFAbbreviationDeclaration abbrevDeclaration;
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t prevAbbrAode = 0;
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  while (abbrevDeclaration.extract(data, offset_ptr)) {
2372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Decls.push_back(abbrevDeclaration);
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (IdxOffset == 0) {
2572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      IdxOffset = abbrevDeclaration.getCode();
2672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    } else {
2772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (prevAbbrAode + 1 != abbrevDeclaration.getCode())
2872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        IdxOffset = UINT32_MAX;// Out of order indexes, we can't do O(1) lookups
2972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
3072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    prevAbbrAode = abbrevDeclaration.getCode();
3172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
3272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return beginOffset != *offset_ptr;
3372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
3472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
3572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  for (unsigned i = 0, e = Decls.size(); i != e; ++i)
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Decls[i].dump(OS);
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFAbbreviationDeclaration*
4172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(uint32_t abbrCode)
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const {
4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (IdxOffset == UINT32_MAX) {
4472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFAbbreviationDeclarationCollConstIter pos;
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFAbbreviationDeclarationCollConstIter end = Decls.end();
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    for (pos = Decls.begin(); pos != end; ++pos) {
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (pos->getCode() == abbrCode)
4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        return &(*pos);
4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  } else {
5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t idx = abbrCode - IdxOffset;
5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (idx < Decls.size())
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return &Decls[idx];
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return NULL;
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugAbbrev::DWARFDebugAbbrev() :
594aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  AbbrevCollMap(),
604aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  PrevAbbrOffsetPos(AbbrevCollMap.end()) {}
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugAbbrev::parse(DataExtractor data) {
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = 0;
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  while (data.isValidOffset(offset)) {
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t initial_cu_offset = offset;
6872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFAbbreviationDeclarationSet abbrevDeclSet;
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrevDeclSet.extract(data, &offset))
714aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer      AbbrevCollMap[initial_cu_offset] = abbrevDeclSet;
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    else
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      break;
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
754aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  PrevAbbrOffsetPos = AbbrevCollMap.end();
7672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
7772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugAbbrev::dump(raw_ostream &OS) const {
794aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  if (AbbrevCollMap.empty()) {
8072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << "< EMPTY >\n";
8172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFAbbreviationDeclarationCollMapConstIter pos;
854aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  for (pos = AbbrevCollMap.begin(); pos != AbbrevCollMap.end(); ++pos) {
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << format("Abbrev table for offset: 0x%8.8x\n", pos->first);
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    pos->second.dump(OS);
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFAbbreviationDeclarationSet*
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const {
934aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  DWARFAbbreviationDeclarationCollMapConstIter end = AbbrevCollMap.end();
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFAbbreviationDeclarationCollMapConstIter pos;
954aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  if (PrevAbbrOffsetPos != end &&
964aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer      PrevAbbrOffsetPos->first == cu_abbr_offset) {
974aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    return &(PrevAbbrOffsetPos->second);
9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  } else {
994aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    pos = AbbrevCollMap.find(cu_abbr_offset);
1004aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer    PrevAbbrOffsetPos = pos;
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
10272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1034aa3fea8b13b91800c908f8e7d74fad96adba69aBenjamin Kramer  if (pos != AbbrevCollMap.end())
10472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return &(pos->second);
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return NULL;
10672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
107