mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-03 00:33:09 +00:00
Crude Dwarf global variable debugging.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
42a162ed80
commit
52060a0e71
@ -445,13 +445,17 @@ namespace llvm {
|
|||||||
class DwarfWriter;
|
class DwarfWriter;
|
||||||
class DWContext;
|
class DWContext;
|
||||||
class MachineDebugInfo;
|
class MachineDebugInfo;
|
||||||
|
class MachineFunction;
|
||||||
|
class Module;
|
||||||
|
class Type;
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DWLabel - Labels are used to track locations in the assembler file.
|
// DWLabel - Labels are used to track locations in the assembler file.
|
||||||
// Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a
|
// Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a
|
||||||
// category of label (Ex. location) and number is a value unique in that
|
// category of label (Ex. location) and number is a value unique in that
|
||||||
// category.
|
// category.
|
||||||
struct DWLabel {
|
class DWLabel {
|
||||||
|
public:
|
||||||
const char *Tag; // Label category tag. Should always be
|
const char *Tag; // Label category tag. Should always be
|
||||||
// a staticly declared C string.
|
// a staticly declared C string.
|
||||||
unsigned Number; // Unique number.
|
unsigned Number; // Unique number.
|
||||||
@ -620,15 +624,15 @@ namespace llvm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DIELabel - A simple label expression DIE.
|
// DIEDwarfLabel - A Dwarf internal label expression DIE.
|
||||||
//
|
//
|
||||||
struct DIELabel : public DIEValue {
|
struct DIEDwarfLabel : public DIEValue {
|
||||||
const DWLabel Label;
|
const DWLabel Label;
|
||||||
|
|
||||||
DIELabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
|
DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast.
|
// Implement isa/cast/dyncast.
|
||||||
static bool classof(const DIELabel *) { return true; }
|
static bool classof(const DIEDwarfLabel *) { return true; }
|
||||||
static bool classof(const DIEValue *L) { return L->Type == isLabel; }
|
static bool classof(const DIEValue *L) { return L->Type == isLabel; }
|
||||||
|
|
||||||
/// EmitValue - Emit label value.
|
/// EmitValue - Emit label value.
|
||||||
@ -642,15 +646,15 @@ namespace llvm {
|
|||||||
|
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DIEAsIsLabel - An exact name of a label.
|
// DIEObjectLabel - A label to an object in code or data.
|
||||||
//
|
//
|
||||||
struct DIEAsIsLabel : public DIEValue {
|
struct DIEObjectLabel : public DIEValue {
|
||||||
const std::string Label;
|
const std::string Label;
|
||||||
|
|
||||||
DIEAsIsLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {}
|
DIEObjectLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast.
|
// Implement isa/cast/dyncast.
|
||||||
static bool classof(const DIEAsIsLabel *) { return true; }
|
static bool classof(const DIEObjectLabel *) { return true; }
|
||||||
static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; }
|
static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; }
|
||||||
|
|
||||||
/// EmitValue - Emit label value.
|
/// EmitValue - Emit label value.
|
||||||
@ -752,10 +756,10 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label);
|
void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label);
|
||||||
|
|
||||||
/// AddAsIsLabel - Add a non-Dwarf label attribute data and value.
|
/// AddObjectLabel - Add a non-Dwarf label attribute data and value.
|
||||||
///
|
///
|
||||||
void AddAsIsLabel(unsigned Attribute, unsigned Form,
|
void AddObjectLabel(unsigned Attribute, unsigned Form,
|
||||||
const std::string &Label);
|
const std::string &Label);
|
||||||
|
|
||||||
/// AddDelta - Add a label delta attribute data and value.
|
/// AddDelta - Add a label delta attribute data and value.
|
||||||
///
|
///
|
||||||
@ -781,13 +785,15 @@ namespace llvm {
|
|||||||
class DWContext {
|
class DWContext {
|
||||||
private:
|
private:
|
||||||
DwarfWriter &DW; // DwarfWriter for global information.
|
DwarfWriter &DW; // DwarfWriter for global information.
|
||||||
|
DWContext *Parent; // Next context level searched.
|
||||||
DIE *Owner; // Owning debug information entry.
|
DIE *Owner; // Owning debug information entry.
|
||||||
std::map<std::string, DIE*> Types; // Named types in context.
|
std::map<const Type *, DIE*> Types; // Named types in context.
|
||||||
std::map<std::string, DIE*> Variables;// Named variables in context.
|
std::map<std::string, DIE*> Variables;// Named variables in context.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DWContext(DwarfWriter &D, DIE *O)
|
DWContext(DwarfWriter &D, DWContext *P, DIE *O)
|
||||||
: DW(D)
|
: DW(D)
|
||||||
|
, Parent(P)
|
||||||
, Owner(O)
|
, Owner(O)
|
||||||
, Types()
|
, Types()
|
||||||
, Variables()
|
, Variables()
|
||||||
@ -796,16 +802,15 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
~DWContext() {}
|
~DWContext() {}
|
||||||
|
|
||||||
/// NewBasicType - Creates a new basic type, if necessary, then adds in the
|
/// NewBasicType - Creates a new basic type, if necessary, then adds to the
|
||||||
/// context and owner.
|
/// context and owner.
|
||||||
DIE *NewBasicType(const std::string &Name, unsigned Size,
|
DIE *NewBasicType(const Type *Ty, unsigned Size, unsigned Align);
|
||||||
unsigned Encoding);
|
|
||||||
|
|
||||||
/// NewVariable - Creates a basic variable, if necessary, then adds in the
|
/// NewVariable - Creates a basic variable, if necessary, then adds to the
|
||||||
/// context and owner.
|
/// context and owner.
|
||||||
DIE *NewVariable(const std::string &Name,
|
DIE *NewGlobalVariable(const std::string &Name,
|
||||||
unsigned SourceFileID, unsigned Line,
|
const std::string &MangledName,
|
||||||
DIE *Type, bool IsExternal);
|
DIE *Type);
|
||||||
};
|
};
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
@ -1039,6 +1044,14 @@ public:
|
|||||||
/// NewGlobalEntity - Make the entity visible globally using the given name.
|
/// NewGlobalEntity - Make the entity visible globally using the given name.
|
||||||
///
|
///
|
||||||
void NewGlobalEntity(const std::string &Name, DIE *Entity);
|
void NewGlobalEntity(const std::string &Name, DIE *Entity);
|
||||||
|
|
||||||
|
/// NewGlobalVariable - Add a new global variable DIE to the context.
|
||||||
|
///
|
||||||
|
void NewGlobalVariable(DWContext *Context,
|
||||||
|
const std::string &Name,
|
||||||
|
const std::string &MangledName,
|
||||||
|
const Type *Ty,
|
||||||
|
unsigned Size, unsigned Align);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// NewCompileUnit - Create new compile unit information.
|
/// NewCompileUnit - Create new compile unit information.
|
||||||
@ -1106,39 +1119,47 @@ private:
|
|||||||
///
|
///
|
||||||
void EmitDebugMacInfo();
|
void EmitDebugMacInfo();
|
||||||
|
|
||||||
|
/// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and
|
||||||
|
/// header file.
|
||||||
|
void ConstructCompileUnitDIEs();
|
||||||
|
|
||||||
|
/// ConstructGlobalDIEs - Create DIEs for each of the externally visible global
|
||||||
|
/// variables.
|
||||||
|
void ConstructGlobalDIEs(Module &M);
|
||||||
|
|
||||||
/// ShouldEmitDwarf - Returns true if Dwarf declarations should be made.
|
/// ShouldEmitDwarf - Returns true if Dwarf declarations should be made.
|
||||||
/// When called it also checks to see if debug info is newly available. if
|
/// When called it also checks to see if debug info is newly available. if
|
||||||
/// so the initial Dwarf headers are emitted.
|
/// so the initial Dwarf headers are emitted.
|
||||||
bool ShouldEmitDwarf();
|
bool ShouldEmitDwarf();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DwarfWriter(std::ostream &o, AsmPrinter *ap);
|
DwarfWriter(std::ostream &OS, AsmPrinter *A);
|
||||||
virtual ~DwarfWriter();
|
virtual ~DwarfWriter();
|
||||||
|
|
||||||
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
|
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
|
||||||
/// created it. Set by the target AsmPrinter.
|
/// created it. Set by the target AsmPrinter.
|
||||||
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
|
void SetDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; }
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Main entry points.
|
// Main entry points.
|
||||||
//
|
//
|
||||||
|
|
||||||
/// BeginModule - Emit all Dwarf sections that should come prior to the
|
/// BeginModule - Emit all Dwarf sections that should come prior to the
|
||||||
/// content.
|
/// content.
|
||||||
void BeginModule();
|
void BeginModule(Module &M);
|
||||||
|
|
||||||
/// EndModule - Emit all Dwarf sections that should come after the content.
|
/// EndModule - Emit all Dwarf sections that should come after the content.
|
||||||
///
|
///
|
||||||
void EndModule();
|
void EndModule(Module &M);
|
||||||
|
|
||||||
/// BeginFunction - Gather pre-function debug information.
|
/// BeginFunction - Gather pre-function debug information.
|
||||||
///
|
///
|
||||||
void BeginFunction();
|
void BeginFunction(MachineFunction &MF);
|
||||||
|
|
||||||
/// EndFunction - Gather and emit post-function debug information.
|
/// EndFunction - Gather and emit post-function debug information.
|
||||||
///
|
///
|
||||||
void EndFunction();
|
void EndFunction(MachineFunction &MF);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end llvm namespace
|
} // end llvm namespace
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
#include "llvm/CodeGen/DwarfWriter.h"
|
#include "llvm/CodeGen/DwarfWriter.h"
|
||||||
|
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
|
#include "llvm/Module.h"
|
||||||
|
#include "llvm/Type.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Support/Mangler.h"
|
||||||
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -588,7 +592,7 @@ bool DIEAbbrev::operator==(const DIEAbbrev &DA) const {
|
|||||||
if (ChildrenFlag != DA.ChildrenFlag) return false;
|
if (ChildrenFlag != DA.ChildrenFlag) return false;
|
||||||
if (Data.size() != DA.Data.size()) return false;
|
if (Data.size() != DA.Data.size()) return false;
|
||||||
|
|
||||||
for (unsigned i = 0, N = Data.size(); i < N; i++) {
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
||||||
if (Data[i] != DA.Data[i]) return false;
|
if (Data[i] != DA.Data[i]) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +606,7 @@ bool DIEAbbrev::operator<(const DIEAbbrev &DA) const {
|
|||||||
if (ChildrenFlag != DA.ChildrenFlag) return ChildrenFlag < DA.ChildrenFlag;
|
if (ChildrenFlag != DA.ChildrenFlag) return ChildrenFlag < DA.ChildrenFlag;
|
||||||
if (Data.size() != DA.Data.size()) return Data.size() < DA.Data.size();
|
if (Data.size() != DA.Data.size()) return Data.size() < DA.Data.size();
|
||||||
|
|
||||||
for (unsigned i = 0, N = Data.size(); i < N; i++) {
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
||||||
if (Data[i] != DA.Data[i]) return Data[i] < DA.Data[i];
|
if (Data[i] != DA.Data[i]) return Data[i] < DA.Data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,7 +625,7 @@ void DIEAbbrev::Emit(const DwarfWriter &DW) const {
|
|||||||
DW.EOL(ChildrenString(ChildrenFlag));
|
DW.EOL(ChildrenString(ChildrenFlag));
|
||||||
|
|
||||||
// For each attribute description.
|
// For each attribute description.
|
||||||
for (unsigned i = 0, N = Data.size(); i < N; i++) {
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
||||||
const DIEAbbrevData &AttrData = Data[i];
|
const DIEAbbrevData &AttrData = Data[i];
|
||||||
|
|
||||||
// Emit attribute type.
|
// Emit attribute type.
|
||||||
@ -648,7 +652,7 @@ void DIEAbbrev::Emit(const DwarfWriter &DW) const {
|
|||||||
<< ChildrenString(ChildrenFlag)
|
<< ChildrenString(ChildrenFlag)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
for (unsigned i = 0, N = Data.size(); i < N; i++) {
|
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
|
||||||
O << " "
|
O << " "
|
||||||
<< AttributeString(Data[i].getAttribute())
|
<< AttributeString(Data[i].getAttribute())
|
||||||
<< " "
|
<< " "
|
||||||
@ -708,13 +712,13 @@ unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
|
|
||||||
/// EmitValue - Emit label value.
|
/// EmitValue - Emit label value.
|
||||||
///
|
///
|
||||||
void DIELabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
void DIEDwarfLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
DW.EmitReference(Label);
|
DW.EmitReference(Label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SizeOf - Determine size of label value in bytes.
|
/// SizeOf - Determine size of label value in bytes.
|
||||||
///
|
///
|
||||||
unsigned DIELabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
unsigned DIEDwarfLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||||
return DW.getAddressSize();
|
return DW.getAddressSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,14 +726,20 @@ unsigned DIELabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
|
|
||||||
/// EmitValue - Emit label value.
|
/// EmitValue - Emit label value.
|
||||||
///
|
///
|
||||||
void DIEAsIsLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
void DIEObjectLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
|
DW.EmitByte(sizeof(int8_t) + DW.getAddressSize());
|
||||||
|
DW.EOL("DW_FORM_block1 length");
|
||||||
|
|
||||||
|
DW.EmitByte(DW_OP_addr);
|
||||||
|
DW.EOL("DW_OP_addr");
|
||||||
|
|
||||||
DW.EmitReference(Label);
|
DW.EmitReference(Label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SizeOf - Determine size of label value in bytes.
|
/// SizeOf - Determine size of label value in bytes.
|
||||||
///
|
///
|
||||||
unsigned DIEAsIsLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
unsigned DIEObjectLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||||
return DW.getAddressSize();
|
return sizeof(int8_t) + sizeof(int8_t) + DW.getAddressSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -774,11 +784,11 @@ DIE::DIE(unsigned Tag, unsigned ChildrenFlag)
|
|||||||
DIE::~DIE() {
|
DIE::~DIE() {
|
||||||
if (Abbrev) delete Abbrev;
|
if (Abbrev) delete Abbrev;
|
||||||
|
|
||||||
for (unsigned i = 0, N = Children.size(); i < N; i++) {
|
for (unsigned i = 0, N = Children.size(); i < N; ++i) {
|
||||||
delete Children[i];
|
delete Children[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned j = 0, M = Values.size(); j < M; j++) {
|
for (unsigned j = 0, M = Values.size(); j < M; ++j) {
|
||||||
delete Values[j];
|
delete Values[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -817,15 +827,15 @@ void DIE::AddString(unsigned Attribute, unsigned Form,
|
|||||||
void DIE::AddLabel(unsigned Attribute, unsigned Form,
|
void DIE::AddLabel(unsigned Attribute, unsigned Form,
|
||||||
const DWLabel &Label) {
|
const DWLabel &Label) {
|
||||||
Abbrev->AddAttribute(Attribute, Form);
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
Values.push_back(new DIELabel(Label));
|
Values.push_back(new DIEDwarfLabel(Label));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AddAsIsLabel - Add an non-Dwarf label attribute data and value.
|
/// AddObjectLabel - Add an non-Dwarf label attribute data and value.
|
||||||
///
|
///
|
||||||
void DIE::AddAsIsLabel(unsigned Attribute, unsigned Form,
|
void DIE::AddObjectLabel(unsigned Attribute, unsigned Form,
|
||||||
const std::string &Label) {
|
const std::string &Label) {
|
||||||
Abbrev->AddAttribute(Attribute, Form);
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
Values.push_back(new DIEAsIsLabel(Label));
|
Values.push_back(new DIEObjectLabel(Label));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AddDelta - Add a label delta attribute data and value.
|
/// AddDelta - Add a label delta attribute data and value.
|
||||||
@ -860,67 +870,112 @@ void DIE::AddChild(DIE *Child) {
|
|||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// NewBasicType - Creates a new basic type if necessary, then adds in the
|
/// NewBasicType - Creates a new basic type if necessary, then adds to the
|
||||||
/// context and owner.
|
/// context and owner.
|
||||||
DIE *DWContext::NewBasicType(const std::string &Name, unsigned Size,
|
DIE *DWContext::NewBasicType(const Type *Ty, unsigned Size, unsigned Align) {
|
||||||
unsigned Encoding) {
|
DIE *TypeDie = Types[Ty];
|
||||||
// FIXME - Just a prototype.
|
|
||||||
DIE *Type = Types[Name];
|
char *Name;
|
||||||
|
unsigned Encoding;
|
||||||
|
|
||||||
// If first occurance of type.
|
// If first occurance of type.
|
||||||
if (!Type) {
|
if (!TypeDie) {
|
||||||
|
const char *Name;
|
||||||
|
unsigned Encoding = 0;
|
||||||
|
|
||||||
|
switch (Ty->getTypeID()) {
|
||||||
|
case Type::UByteTyID:
|
||||||
|
Name = "unsigned char";
|
||||||
|
Encoding = DW_ATE_unsigned_char;
|
||||||
|
break;
|
||||||
|
case Type::SByteTyID:
|
||||||
|
Name = "char";
|
||||||
|
Encoding = DW_ATE_signed_char;
|
||||||
|
break;
|
||||||
|
case Type::UShortTyID:
|
||||||
|
Name = "unsigned short";
|
||||||
|
Encoding = DW_ATE_unsigned;
|
||||||
|
break;
|
||||||
|
case Type::ShortTyID:
|
||||||
|
Name = "short";
|
||||||
|
Encoding = DW_ATE_signed;
|
||||||
|
break;
|
||||||
|
case Type::UIntTyID:
|
||||||
|
Name = "unsigned int";
|
||||||
|
Encoding = DW_ATE_unsigned;
|
||||||
|
break;
|
||||||
|
case Type::IntTyID:
|
||||||
|
Name = "int";
|
||||||
|
Encoding = DW_ATE_signed;
|
||||||
|
break;
|
||||||
|
case Type::ULongTyID:
|
||||||
|
Name = "unsigned long long";
|
||||||
|
Encoding = DW_ATE_unsigned;
|
||||||
|
break;
|
||||||
|
case Type::LongTyID:
|
||||||
|
Name = "long long";
|
||||||
|
Encoding = DW_ATE_signed;
|
||||||
|
break;
|
||||||
|
case Type::FloatTyID:
|
||||||
|
Name = "float";
|
||||||
|
Encoding = DW_ATE_float;
|
||||||
|
break;
|
||||||
|
case Type::DoubleTyID:
|
||||||
|
Name = "float";
|
||||||
|
Encoding = DW_ATE_float;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// FIXME - handle more complex types.
|
||||||
|
Name = "unknown";
|
||||||
|
Encoding = DW_ATE_address;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// construct the type DIE.
|
// construct the type DIE.
|
||||||
Type = new DIE(DW_TAG_base_type, DW_CHILDREN_no);
|
TypeDie = new DIE(DW_TAG_base_type, DW_CHILDREN_no);
|
||||||
Type->AddString(DW_AT_name, DW_FORM_string, Name);
|
TypeDie->AddString(DW_AT_name, DW_FORM_string, Name);
|
||||||
Type->AddInt (DW_AT_byte_size, DW_FORM_data1, Size);
|
TypeDie->AddInt (DW_AT_byte_size, DW_FORM_data1, Size);
|
||||||
Type->AddInt (DW_AT_encoding, DW_FORM_data1, Encoding);
|
TypeDie->AddInt (DW_AT_encoding, DW_FORM_data1, Encoding);
|
||||||
Type->Complete(DW);
|
TypeDie->Complete(DW);
|
||||||
|
|
||||||
// Add to context owner.
|
// Add to context owner.
|
||||||
Owner->AddChild(Type);
|
Owner->AddChild(TypeDie);
|
||||||
|
|
||||||
// Add to map.
|
// Add to map.
|
||||||
Types[Name] = Type;
|
Types[Ty] = TypeDie;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Type;
|
return TypeDie;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NewVariable - Creates a basic variable, if necessary, then adds in the
|
/// NewGlobalVariable - Creates a global variable, if necessary, then adds in
|
||||||
/// context and owner.
|
/// the context and owner.
|
||||||
DIE *DWContext::NewVariable(const std::string &Name,
|
DIE *DWContext::NewGlobalVariable(const std::string &Name,
|
||||||
unsigned SourceFileID, unsigned Line,
|
const std::string &MangledName,
|
||||||
DIE *Type, bool IsExternal) {
|
DIE *Type) {
|
||||||
// FIXME - Just a prototype.
|
DIE *VariableDie = Variables[MangledName];
|
||||||
DIE *Variable = Variables[Name];
|
|
||||||
|
|
||||||
// If first occurance of variable.
|
// If first occurance of variable.
|
||||||
if (!Variable) {
|
if (!VariableDie) {
|
||||||
assert(IsExternal && "Internal variables not handled yet");
|
// FIXME - need source file name line number.
|
||||||
Variable = new DIE(DW_TAG_variable, DW_CHILDREN_no);
|
VariableDie = new DIE(DW_TAG_variable, DW_CHILDREN_no);
|
||||||
Variable->AddString (DW_AT_name, DW_FORM_string, Name);
|
VariableDie->AddString (DW_AT_name, DW_FORM_string, Name);
|
||||||
Variable->AddInt (DW_AT_decl_file, 0, SourceFileID);
|
VariableDie->AddInt (DW_AT_decl_file, 0, 0);
|
||||||
Variable->AddInt (DW_AT_decl_line, 0, Line);
|
VariableDie->AddInt (DW_AT_decl_line, 0, 0);
|
||||||
Variable->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
|
VariableDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
|
||||||
Variable->AddInt (DW_AT_external, DW_FORM_flag, (int)IsExternal);
|
VariableDie->AddInt (DW_AT_external, DW_FORM_flag, 1);
|
||||||
// FIXME - needs to be an expression.
|
// FIXME - needs to be a proper expression.
|
||||||
Variable->AddAsIsLabel(DW_AT_location, DW_FORM_block1,
|
VariableDie->AddObjectLabel(DW_AT_location, DW_FORM_block1, MangledName);
|
||||||
std::string("_")+Name+".b");
|
VariableDie->Complete(DW);
|
||||||
Variable->Complete(DW);
|
|
||||||
|
|
||||||
// Add to context owner.
|
// Add to context owner.
|
||||||
Owner->AddChild(Variable);
|
Owner->AddChild(VariableDie);
|
||||||
|
|
||||||
// Add to map.
|
// Add to map.
|
||||||
Variables[Name] = Variable;
|
Variables[MangledName] = VariableDie;
|
||||||
|
|
||||||
// If external add to visible names.
|
|
||||||
if (IsExternal) {
|
|
||||||
DW.NewGlobalEntity(Name, Variable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Variable;
|
return VariableDie;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -1048,7 +1103,7 @@ void DwarfWriter::EmitLong(int Value) const {
|
|||||||
void DwarfWriter::EmitString(const std::string &String) const {
|
void DwarfWriter::EmitString(const std::string &String) const {
|
||||||
O << Asm->AsciiDirective
|
O << Asm->AsciiDirective
|
||||||
<< "\"";
|
<< "\"";
|
||||||
for (unsigned i = 0, N = String.size(); i < N; i++) {
|
for (unsigned i = 0, N = String.size(); i < N; ++i) {
|
||||||
unsigned char C = String[i];
|
unsigned char C = String[i];
|
||||||
|
|
||||||
if (!isascii(C) || iscntrl(C)) {
|
if (!isascii(C) || iscntrl(C)) {
|
||||||
@ -1134,7 +1189,7 @@ void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
|
|||||||
|
|
||||||
PrintLabelName("set", SetCounter);
|
PrintLabelName("set", SetCounter);
|
||||||
|
|
||||||
SetCounter++;
|
++SetCounter;
|
||||||
} else {
|
} else {
|
||||||
if (AddressSize == sizeof(int32_t))
|
if (AddressSize == sizeof(int32_t))
|
||||||
O << Asm->Data32bitsDirective;
|
O << Asm->Data32bitsDirective;
|
||||||
@ -1163,17 +1218,30 @@ DWLabel DwarfWriter::NewString(const std::string &String) {
|
|||||||
/// NewGlobalType - Make the type visible globally using the given name.
|
/// NewGlobalType - Make the type visible globally using the given name.
|
||||||
///
|
///
|
||||||
void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) {
|
void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) {
|
||||||
// FIXME - check for duplication.
|
assert(!GlobalTypes[Name] && "Duplicate global type");
|
||||||
GlobalTypes[Name] = Type;
|
GlobalTypes[Name] = Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NewGlobalEntity - Make the entity visible globally using the given name.
|
/// NewGlobalEntity - Make the entity visible globally using the given name.
|
||||||
///
|
///
|
||||||
void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) {
|
void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) {
|
||||||
// FIXME - check for duplication.
|
assert(!GlobalEntities[Name] && "Duplicate global variable or function");
|
||||||
GlobalEntities[Name] = Entity;
|
GlobalEntities[Name] = Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// NewGlobalVariable - Add a new global variable DIE to the context.
|
||||||
|
///
|
||||||
|
void DwarfWriter::NewGlobalVariable(DWContext *Context,
|
||||||
|
const std::string &Name,
|
||||||
|
const std::string &MangledName,
|
||||||
|
const Type *Ty,
|
||||||
|
unsigned Size, unsigned Align) {
|
||||||
|
// Get the DIE type for the global.
|
||||||
|
DIE *Type = Context->NewBasicType(Ty, Size, Align);
|
||||||
|
DIE *Variable = Context->NewGlobalVariable(Name, MangledName, Type);
|
||||||
|
NewGlobalEntity(Name, Variable);
|
||||||
|
}
|
||||||
|
|
||||||
/// NewCompileUnit - Create new compile unit information.
|
/// NewCompileUnit - Create new compile unit information.
|
||||||
///
|
///
|
||||||
DIE *DwarfWriter::NewCompileUnit(const std::string &Directory,
|
DIE *DwarfWriter::NewCompileUnit(const std::string &Directory,
|
||||||
@ -1225,6 +1293,7 @@ void DwarfWriter::EmitDIE(DIE *Die) const {
|
|||||||
EmitULEB128Bytes(AbbrevID);
|
EmitULEB128Bytes(AbbrevID);
|
||||||
EOL(std::string("Abbrev [" +
|
EOL(std::string("Abbrev [" +
|
||||||
utostr(AbbrevID) +
|
utostr(AbbrevID) +
|
||||||
|
"] " +
|
||||||
TagString(Abbrev.getTag())) +
|
TagString(Abbrev.getTag())) +
|
||||||
" ");
|
" ");
|
||||||
|
|
||||||
@ -1232,7 +1301,7 @@ void DwarfWriter::EmitDIE(DIE *Die) const {
|
|||||||
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
||||||
|
|
||||||
// Emit the DIE attribute values.
|
// Emit the DIE attribute values.
|
||||||
for (unsigned i = 0, N = Values.size(); i < N; i++) {
|
for (unsigned i = 0, N = Values.size(); i < N; ++i) {
|
||||||
unsigned Attr = AbbrevData[i].getAttribute();
|
unsigned Attr = AbbrevData[i].getAttribute();
|
||||||
unsigned Form = AbbrevData[i].getForm();
|
unsigned Form = AbbrevData[i].getForm();
|
||||||
assert(Form && "Too many attributes for DIE (check abbreviation)");
|
assert(Form && "Too many attributes for DIE (check abbreviation)");
|
||||||
@ -1256,7 +1325,7 @@ void DwarfWriter::EmitDIE(DIE *Die) const {
|
|||||||
if (Abbrev.getChildrenFlag() == DW_CHILDREN_yes) {
|
if (Abbrev.getChildrenFlag() == DW_CHILDREN_yes) {
|
||||||
const std::vector<DIE *> &Children = Die->getChildren();
|
const std::vector<DIE *> &Children = Die->getChildren();
|
||||||
|
|
||||||
for (unsigned j = 0, M = Children.size(); j < M; j++) {
|
for (unsigned j = 0, M = Children.size(); j < M; ++j) {
|
||||||
// FIXME - handle sibling offsets.
|
// FIXME - handle sibling offsets.
|
||||||
// FIXME - handle all DIE types.
|
// FIXME - handle all DIE types.
|
||||||
EmitDIE(Children[j]);
|
EmitDIE(Children[j]);
|
||||||
@ -1283,7 +1352,7 @@ unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) const {
|
|||||||
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
||||||
|
|
||||||
// Emit the DIE attribute values.
|
// Emit the DIE attribute values.
|
||||||
for (unsigned i = 0, N = Values.size(); i < N; i++) {
|
for (unsigned i = 0, N = Values.size(); i < N; ++i) {
|
||||||
// Size attribute value.
|
// Size attribute value.
|
||||||
Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
|
Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
|
||||||
}
|
}
|
||||||
@ -1292,7 +1361,7 @@ unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) const {
|
|||||||
if (Abbrev.getChildrenFlag() == DW_CHILDREN_yes) {
|
if (Abbrev.getChildrenFlag() == DW_CHILDREN_yes) {
|
||||||
const std::vector<DIE *> &Children = Die->getChildren();
|
const std::vector<DIE *> &Children = Die->getChildren();
|
||||||
|
|
||||||
for (unsigned j = 0, M = Children.size(); j < M; j++) {
|
for (unsigned j = 0, M = Children.size(); j < M; ++j) {
|
||||||
// FIXME - handle sibling offsets.
|
// FIXME - handle sibling offsets.
|
||||||
// FIXME - handle all DIE types.
|
// FIXME - handle all DIE types.
|
||||||
Offset = SizeAndOffsetDie(Children[j], Offset);
|
Offset = SizeAndOffsetDie(Children[j], Offset);
|
||||||
@ -1316,7 +1385,7 @@ void DwarfWriter::SizeAndOffsets() {
|
|||||||
sizeof(int8_t); // Pointer Size (in bytes)
|
sizeof(int8_t); // Pointer Size (in bytes)
|
||||||
|
|
||||||
// Process each compile unit.
|
// Process each compile unit.
|
||||||
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
|
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
|
||||||
Offset = SizeAndOffsetDie(CompileUnits[i], Offset);
|
Offset = SizeAndOffsetDie(CompileUnits[i], Offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1348,7 +1417,7 @@ void DwarfWriter::EmitDebugInfo() const {
|
|||||||
EmitByte(AddressSize); EOL("Address Size (in bytes)");
|
EmitByte(AddressSize); EOL("Address Size (in bytes)");
|
||||||
|
|
||||||
// Process each compile unit.
|
// Process each compile unit.
|
||||||
for (unsigned i = 0; i < N; i++) {
|
for (unsigned i = 0; i < N; ++i) {
|
||||||
EmitDIE(CompileUnits[i]);
|
EmitDIE(CompileUnits[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1368,7 +1437,7 @@ void DwarfWriter::EmitAbbreviations() const {
|
|||||||
|
|
||||||
// For each abbrevation.
|
// For each abbrevation.
|
||||||
for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
|
for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
|
||||||
AbbrevID <= NAID; AbbrevID++) {
|
AbbrevID <= NAID; ++AbbrevID) {
|
||||||
// Get abbreviation data
|
// Get abbreviation data
|
||||||
const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
|
const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
|
||||||
|
|
||||||
@ -1432,14 +1501,14 @@ void DwarfWriter::EmitDebugLines() const {
|
|||||||
|
|
||||||
// Emit directories.
|
// Emit directories.
|
||||||
for (unsigned DirectoryID = 1, NDID = Directories.size();
|
for (unsigned DirectoryID = 1, NDID = Directories.size();
|
||||||
DirectoryID <= NDID; DirectoryID++) {
|
DirectoryID <= NDID; ++DirectoryID) {
|
||||||
EmitString(Directories[DirectoryID]); EOL("Directory");
|
EmitString(Directories[DirectoryID]); EOL("Directory");
|
||||||
}
|
}
|
||||||
EmitByte(0); EOL("End of directories");
|
EmitByte(0); EOL("End of directories");
|
||||||
|
|
||||||
// Emit files.
|
// Emit files.
|
||||||
for (unsigned SourceID = 1, NSID = SourceFiles.size();
|
for (unsigned SourceID = 1, NSID = SourceFiles.size();
|
||||||
SourceID <= NSID; SourceID++) {
|
SourceID <= NSID; ++SourceID) {
|
||||||
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
||||||
EmitString(SourceFile.getName()); EOL("Source");
|
EmitString(SourceFile.getName()); EOL("Source");
|
||||||
EmitULEB128Bytes(SourceFile.getDirectoryID()); EOL("Directory #");
|
EmitULEB128Bytes(SourceFile.getDirectoryID()); EOL("Directory #");
|
||||||
@ -1458,7 +1527,7 @@ void DwarfWriter::EmitDebugLines() const {
|
|||||||
unsigned Line = 1;
|
unsigned Line = 1;
|
||||||
|
|
||||||
// Construct rows of the address, source, line, column matrix.
|
// Construct rows of the address, source, line, column matrix.
|
||||||
for (unsigned i = 0, N = LineInfos.size(); i < N; i++) {
|
for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
|
||||||
SourceLineInfo *LineInfo = LineInfos[i];
|
SourceLineInfo *LineInfo = LineInfos[i];
|
||||||
|
|
||||||
// Define the line address.
|
// Define the line address.
|
||||||
@ -1533,11 +1602,11 @@ void DwarfWriter::EmitDebugPubNames() {
|
|||||||
EmitDifference("info_end", 0, "info_begin", 0);
|
EmitDifference("info_end", 0, "info_begin", 0);
|
||||||
EOL("Compilation Unit Length");
|
EOL("Compilation Unit Length");
|
||||||
|
|
||||||
for (std::map<std::string, DIE *>::iterator G = GlobalTypes.begin(),
|
for (std::map<std::string, DIE *>::iterator GI = GlobalEntities.begin(),
|
||||||
GE = GlobalTypes.begin();
|
GE = GlobalEntities.end();
|
||||||
G != GE; G++) {
|
GI != GE; ++GI) {
|
||||||
const std::string &Name = (*G).first;
|
const std::string &Name = GI->first;
|
||||||
DIE * Entity = (*G).second;
|
DIE * Entity = GI->second;
|
||||||
|
|
||||||
EmitLong(Entity->getOffset()); EOL("DIE offset");
|
EmitLong(Entity->getOffset()); EOL("DIE offset");
|
||||||
EmitString(Name); EOL("External Name");
|
EmitString(Name); EOL("External Name");
|
||||||
@ -1569,7 +1638,7 @@ void DwarfWriter::EmitDebugStr() {
|
|||||||
|
|
||||||
// For each of strings in teh string pool.
|
// For each of strings in teh string pool.
|
||||||
for (unsigned StringID = 1, N = StringPool.size();
|
for (unsigned StringID = 1, N = StringPool.size();
|
||||||
StringID <= N; StringID++) {
|
StringID <= N; ++StringID) {
|
||||||
// Emit a label for reference from debug information entries.
|
// Emit a label for reference from debug information entries.
|
||||||
EmitLabel("string", StringID);
|
EmitLabel("string", StringID);
|
||||||
// Emit the string itself.
|
// Emit the string itself.
|
||||||
@ -1630,6 +1699,63 @@ void DwarfWriter::EmitDebugMacInfo() {
|
|||||||
Asm->SwitchSection(DwarfMacInfoSection, 0);
|
Asm->SwitchSection(DwarfMacInfoSection, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ConstructCompileUnitDIEs - Create a compile unit DIE for each source and
|
||||||
|
/// header file.
|
||||||
|
void DwarfWriter::ConstructCompileUnitDIEs() {
|
||||||
|
// Get directory and source information.
|
||||||
|
const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
|
||||||
|
const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
|
||||||
|
|
||||||
|
// Construct compile unit DIEs for each source.
|
||||||
|
for (unsigned SourceID = 1, NSID = SourceFiles.size();
|
||||||
|
SourceID <= NSID; ++SourceID) {
|
||||||
|
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
||||||
|
const std::string &Directory = Directories[SourceFile.getDirectoryID()];
|
||||||
|
const std::string &SourceName = SourceFile.getName();
|
||||||
|
DIE *Unit = NewCompileUnit(Directory, SourceName);
|
||||||
|
DWContext *Context = new DWContext(*this, NULL, Unit);
|
||||||
|
CompileUnits.push_back(Unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ConstructGlobalDIEs - Create DIEs for each of the externally visible global
|
||||||
|
/// variables.
|
||||||
|
void DwarfWriter::ConstructGlobalDIEs(Module &M) {
|
||||||
|
const TargetData &TD = Asm->TM.getTargetData();
|
||||||
|
|
||||||
|
// Iterate throu each of the globals.
|
||||||
|
for (Module::const_global_iterator GI = M.global_begin(), GE = M.global_end();
|
||||||
|
GI != GE; ++GI) {
|
||||||
|
if (!GI->hasInitializer()) continue; // External global require no code
|
||||||
|
|
||||||
|
// Check to see if this is a special global used by LLVM, if so, emit it.
|
||||||
|
if (GI->hasAppendingLinkage() && (GI->getName() == "llvm.global_ctors" ||
|
||||||
|
GI->getName() == "llvm.global_dtors"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string Name = Asm->Mang->getValueName(GI);
|
||||||
|
Constant *C = GI->getInitializer();
|
||||||
|
const Type *Ty = C->getType();
|
||||||
|
unsigned Size = TD.getTypeSize(Ty);
|
||||||
|
unsigned Align = TD.getTypeAlignmentShift(Ty);
|
||||||
|
|
||||||
|
if (C->isNullValue() && /* FIXME: Verify correct */
|
||||||
|
(GI->hasInternalLinkage() || GI->hasWeakLinkage() ||
|
||||||
|
GI->hasLinkOnceLinkage())) {
|
||||||
|
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FIXME - Get correct compile unit context.
|
||||||
|
assert(CompileUnits.size() && "No compile units");
|
||||||
|
DWContext *Context = CompileUnits[0]->getContext();
|
||||||
|
|
||||||
|
/// Create new global.
|
||||||
|
NewGlobalVariable(Context, GI->getName(), Name, Ty, Size, Align);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// ShouldEmitDwarf - Determine if Dwarf declarations should be made.
|
/// ShouldEmitDwarf - Determine if Dwarf declarations should be made.
|
||||||
///
|
///
|
||||||
bool DwarfWriter::ShouldEmitDwarf() {
|
bool DwarfWriter::ShouldEmitDwarf() {
|
||||||
@ -1649,52 +1775,52 @@ bool DwarfWriter::ShouldEmitDwarf() {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Main entry points.
|
// Main entry points.
|
||||||
//
|
//
|
||||||
|
|
||||||
DwarfWriter::DwarfWriter(std::ostream &o, AsmPrinter *ap)
|
DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
|
||||||
: O(o)
|
: O(OS)
|
||||||
, Asm(ap)
|
, Asm(A)
|
||||||
, DebugInfo(NULL)
|
, DebugInfo(NULL)
|
||||||
, didInitial(false)
|
, didInitial(false)
|
||||||
, CompileUnits()
|
, CompileUnits()
|
||||||
, Abbreviations()
|
, Abbreviations()
|
||||||
, GlobalTypes()
|
, GlobalTypes()
|
||||||
, GlobalEntities()
|
, GlobalEntities()
|
||||||
, StringPool()
|
, StringPool()
|
||||||
, AddressSize(sizeof(int32_t))
|
, AddressSize(sizeof(int32_t))
|
||||||
, hasLEB128(false)
|
, hasLEB128(false)
|
||||||
, hasDotLoc(false)
|
, hasDotLoc(false)
|
||||||
, hasDotFile(false)
|
, hasDotFile(false)
|
||||||
, needsSet(false)
|
, needsSet(false)
|
||||||
, DwarfAbbrevSection(".debug_abbrev")
|
, DwarfAbbrevSection(".debug_abbrev")
|
||||||
, DwarfInfoSection(".debug_info")
|
, DwarfInfoSection(".debug_info")
|
||||||
, DwarfLineSection(".debug_line")
|
, DwarfLineSection(".debug_line")
|
||||||
, DwarfFrameSection(".debug_frame")
|
, DwarfFrameSection(".debug_frame")
|
||||||
, DwarfPubNamesSection(".debug_pubnames")
|
, DwarfPubNamesSection(".debug_pubnames")
|
||||||
, DwarfPubTypesSection(".debug_pubtypes")
|
, DwarfPubTypesSection(".debug_pubtypes")
|
||||||
, DwarfStrSection(".debug_str")
|
, DwarfStrSection(".debug_str")
|
||||||
, DwarfLocSection(".debug_loc")
|
, DwarfLocSection(".debug_loc")
|
||||||
, DwarfARangesSection(".debug_aranges")
|
, DwarfARangesSection(".debug_aranges")
|
||||||
, DwarfRangesSection(".debug_ranges")
|
, DwarfRangesSection(".debug_ranges")
|
||||||
, DwarfMacInfoSection(".debug_macinfo")
|
, DwarfMacInfoSection(".debug_macinfo")
|
||||||
, TextSection(".text")
|
, TextSection(".text")
|
||||||
, DataSection(".data")
|
, DataSection(".data")
|
||||||
{}
|
{}
|
||||||
DwarfWriter::~DwarfWriter() {
|
DwarfWriter::~DwarfWriter() {
|
||||||
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
|
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
|
||||||
delete CompileUnits[i];
|
delete CompileUnits[i];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// BeginModule - Emit all Dwarf sections that should come prior to the content.
|
/// BeginModule - Emit all Dwarf sections that should come prior to the content.
|
||||||
///
|
///
|
||||||
void DwarfWriter::BeginModule() {
|
void DwarfWriter::BeginModule(Module &M) {
|
||||||
if (!ShouldEmitDwarf()) return;
|
if (!ShouldEmitDwarf()) return;
|
||||||
EOL("Dwarf Begin Module");
|
EOL("Dwarf Begin Module");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EndModule - Emit all Dwarf sections that should come after the content.
|
/// EndModule - Emit all Dwarf sections that should come after the content.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EndModule() {
|
void DwarfWriter::EndModule(Module &M) {
|
||||||
if (!ShouldEmitDwarf()) return;
|
if (!ShouldEmitDwarf()) return;
|
||||||
EOL("Dwarf End Module");
|
EOL("Dwarf End Module");
|
||||||
|
|
||||||
@ -1704,27 +1830,11 @@ void DwarfWriter::EndModule() {
|
|||||||
Asm->SwitchSection(DataSection, 0);
|
Asm->SwitchSection(DataSection, 0);
|
||||||
EmitLabel("data_end", 0);
|
EmitLabel("data_end", 0);
|
||||||
|
|
||||||
// Get directory and source information.
|
// Create all the compile unit DIEs.
|
||||||
const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
|
ConstructCompileUnitDIEs();
|
||||||
const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
|
|
||||||
|
// Create DIEs for each of the externally visible global variables.
|
||||||
// Construct compile unit DIEs for each source.
|
ConstructGlobalDIEs(M);
|
||||||
for (unsigned SourceID = 1, NSID = SourceFiles.size();
|
|
||||||
SourceID <= NSID; SourceID++) {
|
|
||||||
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
|
||||||
const std::string &Directory = Directories[SourceFile.getDirectoryID()];
|
|
||||||
const std::string &SourceName = SourceFile.getName();
|
|
||||||
DIE *Unit = NewCompileUnit(Directory, SourceName);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// FIXME - just testing.
|
|
||||||
DWContext *Context = new DWContext(*this, Unit);
|
|
||||||
DIE *TypeInt = Context->NewBasicType("int", sizeof(int32_t), DW_ATE_signed);
|
|
||||||
Context->NewVariable("MyGlobal", SourceID, 1, TypeInt, true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CompileUnits.push_back(Unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute DIE offsets and sizes.
|
// Compute DIE offsets and sizes.
|
||||||
SizeAndOffsets();
|
SizeAndOffsets();
|
||||||
@ -1765,14 +1875,14 @@ void DwarfWriter::EndModule() {
|
|||||||
|
|
||||||
/// BeginFunction - Gather pre-function debug information.
|
/// BeginFunction - Gather pre-function debug information.
|
||||||
///
|
///
|
||||||
void DwarfWriter::BeginFunction() {
|
void DwarfWriter::BeginFunction(MachineFunction &MF) {
|
||||||
if (!ShouldEmitDwarf()) return;
|
if (!ShouldEmitDwarf()) return;
|
||||||
EOL("Dwarf Begin Function");
|
EOL("Dwarf Begin Function");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EndFunction - Gather and emit post-function debug information.
|
/// EndFunction - Gather and emit post-function debug information.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EndFunction() {
|
void DwarfWriter::EndFunction(MachineFunction &MF) {
|
||||||
if (!ShouldEmitDwarf()) return;
|
if (!ShouldEmitDwarf()) return;
|
||||||
EOL("Dwarf End Function");
|
EOL("Dwarf End Function");
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
O << "\n\n";
|
O << "\n\n";
|
||||||
|
|
||||||
// Emit pre-function debug information.
|
// Emit pre-function debug information.
|
||||||
DW.BeginFunction();
|
DW.BeginFunction(MF);
|
||||||
|
|
||||||
// Print out constants referenced by the function
|
// Print out constants referenced by the function
|
||||||
EmitConstantPool(MF.getConstantPool());
|
EmitConstantPool(MF.getConstantPool());
|
||||||
@ -486,7 +486,7 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit post-function debug information.
|
// Emit post-function debug information.
|
||||||
DW.EndFunction();
|
DW.EndFunction(MF);
|
||||||
|
|
||||||
// We didn't modify anything.
|
// We didn't modify anything.
|
||||||
return false;
|
return false;
|
||||||
@ -502,7 +502,7 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
|
|||||||
Mang->setUseQuotes(true);
|
Mang->setUseQuotes(true);
|
||||||
|
|
||||||
// Emit initial debug information.
|
// Emit initial debug information.
|
||||||
DW.BeginModule();
|
DW.BeginModule(M);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,7 +619,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit initial debug information.
|
// Emit initial debug information.
|
||||||
DW.EndModule();
|
DW.EndModule(M);
|
||||||
|
|
||||||
// Funny Darwin hack: This flag tells the linker that no global symbols
|
// Funny Darwin hack: This flag tells the linker that no global symbols
|
||||||
// contain code that falls through to other global symbols (e.g. the obvious
|
// contain code that falls through to other global symbols (e.g. the obvious
|
||||||
|
Loading…
x
Reference in New Issue
Block a user