Skip to content

Commit

Permalink
Sketch out a DWARF parser.
Browse files Browse the repository at this point in the history
This introduces a new library to LLVM: libDebugInfo. It will provide debug information
parsing to LLVM. Much of the design and some of the code is taken from the LLDB project.

It also contains an llvm-dwarfdump tool that can dump the abbrevs and DIEs from an
object file. It can be used to write tests for DWARF input and output easily.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139627 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
d0k committed Sep 13, 2011
1 parent 8c74f7f commit 72c0d7f
Show file tree
Hide file tree
Showing 24 changed files with 2,046 additions and 2 deletions.
42 changes: 42 additions & 0 deletions include/llvm/DebugInfo/DIContext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===-- DIContext.h ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines DIContext, and abstract data structure that holds
// debug information data.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_DICONTEXT_H
#define LLVM_DEBUGINFO_DICONTEXT_H

#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DILineInfo.h"

namespace llvm {

class raw_ostream;

class DIContext {
public:
virtual ~DIContext();

/// getDWARFContext - get a context for binary DWARF data.
static DIContext *getDWARFContext(bool isLittleEndian,
StringRef infoSection,
StringRef abbrevSection,
StringRef aRangeSection = StringRef(),
StringRef lineSection = StringRef(),
StringRef stringSection = StringRef());

virtual void dump(raw_ostream &OS) = 0;
};

}

#endif
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_subdirectory(Analysis)
add_subdirectory(MC)
add_subdirectory(CompilerDriver)
add_subdirectory(Object)
add_subdirectory(DebugInfo)
add_subdirectory(ExecutionEngine)
add_subdirectory(Target)
add_subdirectory(AsmParser)
Expand Down
13 changes: 13 additions & 0 deletions lib/DebugInfo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
add_llvm_library(LLVMMC
DIContext.cpp
DWARFAbbreviationDeclaration.cpp
DWARFCompileUnit.cpp
DWARFContext.cpp
DWARFDebugAbbrev.cpp
DWARFDebugInfoEntry.cpp
DWARFFormValue.cpp
)

add_llvm_library_dependencies(LLVMDebugInfo
LLVMSupport
)
24 changes: 24 additions & 0 deletions lib/DebugInfo/DIContext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- DIContext.cpp -----------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/DIContext.h"
#include "DWARFContext.h"
using namespace llvm;

DIContext::~DIContext() {}

DIContext *DIContext::getDWARFContext(bool isLittleEndian,
StringRef infoSection,
StringRef abbrevSection,
StringRef aRangeSection,
StringRef lineSection,
StringRef stringSection) {
return new DWARFContextInMemory(isLittleEndian, infoSection, abbrevSection,
aRangeSection, lineSection, stringSection);
}
66 changes: 66 additions & 0 deletions lib/DebugInfo/DWARFAbbreviationDeclaration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DWARFAbbreviationDeclaration.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace dwarf;

bool
DWARFAbbreviationDeclaration::extract(DataExtractor data, uint32_t* offset_ptr){
return extract(data, offset_ptr, data.getULEB128(offset_ptr));
}

bool
DWARFAbbreviationDeclaration::extract(DataExtractor data, uint32_t* offset_ptr,
uint32_t code) {
Code = code;
Attributes.clear();
if (Code) {
Tag = data.getULEB128(offset_ptr);
HasChildren = data.getU8(offset_ptr);

while (data.isValidOffset(*offset_ptr)) {
uint16_t attr = data.getULEB128(offset_ptr);
uint16_t form = data.getULEB128(offset_ptr);

if (attr && form)
Attributes.push_back(DWARFAttribute(attr, form));
else
break;
}

return Tag != 0;
}
else {
Tag = 0;
HasChildren = false;
}

return false;
}

void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
OS << '[' << getCode() << "] " << TagString(getTag()) << "\tDW_CHILDREN_"
<< (hasChildren() ? "yes" : "no") << '\n';
for (unsigned i = 0, e = Attributes.size(); i != e; ++i)
OS << '\t' << AttributeString(Attributes[i].getAttribute())
<< '\t' << FormEncodingString(Attributes[i].getForm()) << '\n';
OS << '\n';
}

uint32_t
DWARFAbbreviationDeclaration::findAttributeIndex(uint16_t attr) const {
for (uint32_t i = 0, e = Attributes.size(); i != e; ++i) {
if (Attributes[i].getAttribute() == attr)
return i;
}
return -1U;
}
54 changes: 54 additions & 0 deletions lib/DebugInfo/DWARFAbbreviationDeclaration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H

#include "DWARFAttribute.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataExtractor.h"

namespace llvm {

class raw_ostream;

class DWARFAbbreviationDeclaration {
uint32_t Code;
uint32_t Tag;
bool HasChildren;
SmallVector<DWARFAttribute, 8> Attributes;
public:
enum { InvalidCode = 0 };
DWARFAbbreviationDeclaration()
: Code(InvalidCode), Tag(0), HasChildren(0) {}

uint32_t getCode() const { return Code; }
uint32_t getTag() const { return Tag; }
bool hasChildren() const { return HasChildren; }
uint32_t getNumAttributes() const { return Attributes.size(); }
uint16_t getAttrByIndex(uint32_t idx) const {
return Attributes.size() > idx ? Attributes[idx].getAttribute() : 0;
}
uint16_t getFormByIndex(uint32_t idx) const {
return Attributes.size() > idx ? Attributes[idx].getForm() : 0;
}

uint32_t findAttributeIndex(uint16_t attr) const;
bool extract(DataExtractor data, uint32_t* offset_ptr);
bool extract(DataExtractor data, uint32_t* offset_ptr, uint32_t code);
bool isValid() const { return Code != 0 && Tag != 0; }
void dump(raw_ostream &OS) const;
const SmallVectorImpl<DWARFAttribute> &getAttributes() const {
return Attributes;
}
};

}

#endif
30 changes: 30 additions & 0 deletions lib/DebugInfo/DWARFAttribute.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//===-- DWARFAttribute.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_DWARFATTRIBUTE_H
#define LLVM_DEBUGINFO_DWARFATTRIBUTE_H

#include "llvm/Support/DataTypes.h"

namespace llvm {

class DWARFAttribute {
uint16_t Attribute;
uint16_t Form;
public:
DWARFAttribute(uint16_t attr, uint16_t form)
: Attribute(attr), Form(form) {}

uint16_t getAttribute() const { return Attribute; }
uint16_t getForm() const { return Form; }
};

}

#endif
Loading

0 comments on commit 72c0d7f

Please sign in to comment.