DWARFDebugAbbrev.cpp revision 72c0d7fdd3d0930c7507060e96aec7d7429a8190
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 Kramer
3672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
3772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  for (unsigned i = 0, e = Decls.size(); i != e; ++i)
3872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    Decls[i].dump(OS);
3972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
4072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
4272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFAbbreviationDeclaration*
4372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(uint32_t abbrCode)
4472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  const {
4572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (IdxOffset == UINT32_MAX) {
4672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFAbbreviationDeclarationCollConstIter pos;
4772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFAbbreviationDeclarationCollConstIter end = Decls.end();
4872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    for (pos = Decls.begin(); pos != end; ++pos) {
4972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      if (pos->getCode() == abbrCode)
5072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer        return &(*pos);
5172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
5272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  } else {
5372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t idx = abbrCode - IdxOffset;
5472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (idx < Decls.size())
5572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      return &Decls[idx];
5672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
5772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return NULL;
5872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
5972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugAbbrev::DWARFDebugAbbrev() :
6172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  m_abbrevCollMap(),
6272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
6372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugAbbrev::parse(DataExtractor data) {
6672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = 0;
6772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
6872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  while (data.isValidOffset(offset)) {
6972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    uint32_t initial_cu_offset = offset;
7072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    DWARFAbbreviationDeclarationSet abbrevDeclSet;
7172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
7272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    if (abbrevDeclSet.extract(data, &offset))
7372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
7472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    else
7572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      break;
7672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
7772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  m_prev_abbr_offset_pos = m_abbrevCollMap.end();
7872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
7972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFDebugAbbrev::dump(raw_ostream &OS) const {
8172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (m_abbrevCollMap.empty()) {
8272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << "< EMPTY >\n";
8372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return;
8472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
8572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
8672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFAbbreviationDeclarationCollMapConstIter pos;
8772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) {
8872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    OS << format("Abbrev table for offset: 0x%8.8x\n", pos->first);
8972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    pos->second.dump(OS);
9072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
9172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
9272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
9372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFAbbreviationDeclarationSet*
9472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin KramerDWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const {
9572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
9672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DWARFAbbreviationDeclarationCollMapConstIter pos;
9772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (m_prev_abbr_offset_pos != end &&
9872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      m_prev_abbr_offset_pos->first == cu_abbr_offset) {
9972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return &(m_prev_abbr_offset_pos->second);
10072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  } else {
10172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    pos = m_abbrevCollMap.find(cu_abbr_offset);
10272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    m_prev_abbr_offset_pos = pos;
10372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
10472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
10572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (pos != m_abbrevCollMap.end())
10672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return &(pos->second);
10772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return NULL;
10872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
109