#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Mangler.h"
+#include "llvm/System/Path.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetData.h"
/// SubprogramCount - The running count of functions being compiled.
///
unsigned SubprogramCount;
+
+ /// Flavor - A unique string indicating what dwarf producer this is, used to
+ /// unique labels.
+ const char * const Flavor;
unsigned SetCounter;
- Dwarf(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
+ Dwarf(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T,
+ const char *flavor)
: O(OS)
, Asm(A)
, TAI(T)
, MF(NULL)
, MMI(NULL)
, SubprogramCount(0)
+ , Flavor(flavor)
, SetCounter(1)
{
}
AsmPrinter *getAsm() const { return Asm; }
MachineModuleInfo *getMMI() const { return MMI; }
const TargetAsmInfo *getTargetAsmInfo() const { return TAI; }
+ const TargetData *getTargetData() const { return TD; }
void PrintRelDirective(bool Force32Bit = false, bool isInSection = false)
const {
if (isInSection && TAI->getDwarfSectionOffsetDirective())
O << TAI->getDwarfSectionOffsetDirective();
- else if (Force32Bit || TAI->getAddressSize() == sizeof(int32_t))
+ else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t))
O << TAI->getData32bitsDirective();
else
O << TAI->getData64bitsDirective();
PrintLabelName(Label.Tag, Label.Number);
}
void PrintLabelName(const char *Tag, unsigned Number) const {
-
O << TAI->getPrivateGlobalPrefix() << Tag;
if (Number) O << Number;
}
+ void PrintLabelName(const char *Tag, unsigned Number,
+ const char *Suffix) const {
+ O << TAI->getPrivateGlobalPrefix() << Tag;
+ if (Number) O << Number;
+ O << Suffix;
+ }
+
/// EmitLabel - Emit location label for internal use by Dwarf.
///
void EmitLabel(DWLabel Label) const {
/// EmitReference - Emit a reference to a label.
///
- void EmitReference(DWLabel Label, bool IsPCRelative = false) const {
- EmitReference(Label.Tag, Label.Number, IsPCRelative);
+ void EmitReference(DWLabel Label, bool IsPCRelative = false,
+ bool Force32Bit = false) const {
+ EmitReference(Label.Tag, Label.Number, IsPCRelative, Force32Bit);
}
void EmitReference(const char *Tag, unsigned Number,
- bool IsPCRelative = false) const {
- PrintRelDirective();
+ bool IsPCRelative = false, bool Force32Bit = false) const {
+ PrintRelDirective(Force32Bit);
PrintLabelName(Tag, Number);
if (IsPCRelative) O << "-" << TAI->getPCSymbol();
}
- void EmitReference(const std::string &Name, bool IsPCRelative = false) const {
- PrintRelDirective();
+ void EmitReference(const std::string &Name, bool IsPCRelative = false,
+ bool Force32Bit = false) const {
+ PrintRelDirective(Force32Bit);
O << Name;
bool IsSmall = false) {
if (TAI->needsSet()) {
O << "\t.set\t";
- PrintLabelName("set", SetCounter);
+ PrintLabelName("set", SetCounter, Flavor);
O << ",";
PrintLabelName(TagHi, NumberHi);
O << "-";
O << "\n";
PrintRelDirective(IsSmall);
-
- PrintLabelName("set", SetCounter);
-
+ PrintLabelName("set", SetCounter, Flavor);
++SetCounter;
} else {
PrintRelDirective(IsSmall);
bool printAbsolute = false;
if (TAI->needsSet()) {
O << "\t.set\t";
- PrintLabelName("set", SetCounter);
+ PrintLabelName("set", SetCounter, Flavor);
O << ",";
PrintLabelName(Label, LabelNumber);
PrintRelDirective(IsSmall);
- PrintLabelName("set", SetCounter);
+ PrintLabelName("set", SetCounter, Flavor);
++SetCounter;
} else {
PrintRelDirective(IsSmall, true);
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
- TAI->getAddressSize() : -TAI->getAddressSize();
+ TD->getPointerSize() : -TD->getPointerSize();
bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0;
for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
ValuesSet.InsertNode(Value, Where);
Values.push_back(Value);
} else {
+ // Already exists, reuse the previous one.
delete Block;
+ Block = cast<DIEBlock>(Value);
}
Die->AddValue(Attribute, Block->BestForm(), Value);
///
DIE *ConstructPointerType(CompileUnit *Unit, const std::string &Name) {
DIE Buffer(DW_TAG_pointer_type);
- AddUInt(&Buffer, DW_AT_byte_size, 0, TAI->getAddressSize());
+ AddUInt(&Buffer, DW_AT_byte_size, 0, TD->getPointerSize());
if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
return Unit->AddDie(Buffer);
}
Asm->EmitInt16(DWARF_VERSION); Asm->EOL("DWARF version number");
EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false);
Asm->EOL("Offset Into Abbrev. Section");
- Asm->EmitInt8(TAI->getAddressSize()); Asm->EOL("Address Size (in bytes)");
+ Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
EmitDIE(Die);
// FIXME - extra padding for gdb bug.
/// EmitDebugLines - Emit source line information.
///
void EmitDebugLines() {
+ // If there are no lines to emit (such as when we're using .loc directives
+ // to emit .debug_line information) don't emit a .debug_line header.
+ if (SectionSourceLines.empty())
+ return;
+
// Minimum line delta, thus ranging from -10..(255-10).
const int MinLineDelta = -(DW_LNS_fixed_advance_pc + 1);
// Maximum line delta, thus ranging from -10..(255-10).
// Define the line address.
Asm->EmitInt8(0); Asm->EOL("Extended Op");
- Asm->EmitInt8(TAI->getAddressSize() + 1); Asm->EOL("Op size");
+ Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size");
Asm->EmitInt8(DW_LNE_set_address); Asm->EOL("DW_LNE_set_address");
EmitReference("label", LabelID); Asm->EOL("Location label");
// Define last address of section.
Asm->EmitInt8(0); Asm->EOL("Extended Op");
- Asm->EmitInt8(TAI->getAddressSize() + 1); Asm->EOL("Op size");
+ Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size");
Asm->EmitInt8(DW_LNE_set_address); Asm->EOL("DW_LNE_set_address");
EmitReference("section_end", j + 1); Asm->EOL("Section end label");
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
- TAI->getAddressSize() : -TAI->getAddressSize();
+ TD->getPointerSize() : -TD->getPointerSize();
// Start the dwarf frame section.
Asm->SwitchToDataSection(TAI->getDwarfFrameSection());
EmitReference("info_begin", Unit->getID());
Asm->EOL("Offset of Compilation Unit Info");
- Asm->EmitInt8(TAI->getAddressSize()); Asm->EOL("Size of Address");
+ Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address");
Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor");
Asm->EmitInt32(0); Asm->EOL("EOM (1)");
Asm->EmitInt32(0); Asm->EOL("EOM (2)");
+ #endif
Asm->EOL();
- #endif
}
/// EmitDebugRanges - Emit visible names into a debug ranges section.
// Main entry points.
//
DwarfDebug(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
- : Dwarf(OS, A, T)
+ : Dwarf(OS, A, T, "dbg")
, CompileUnits()
, AbbreviationsSet(InitAbbreviationsSetSize)
, Abbreviations()
MMI = mmi;
shouldEmit = true;
- // Emit initial sections
- EmitInitial();
-
// Create all the compile unit DIEs.
ConstructCompileUnitDIEs();
// Prime section data.
SectionMap.insert(TAI->getTextSection());
+
+ // Print out .file directives to specify files for .loc directives. These
+ // are printed out early so that they precede any .loc directives.
+ if (TAI->hasDotLocAndDotFile()) {
+ const UniqueVector<SourceFileInfo> &SourceFiles = MMI->getSourceFiles();
+ const UniqueVector<std::string> &Directories = MMI->getDirectories();
+ for (unsigned i = 1, e = SourceFiles.size(); i <= e; ++i) {
+ sys::Path FullPath(Directories[SourceFiles[i].getDirectoryID()]);
+ bool AppendOk = FullPath.appendComponent(SourceFiles[i].getName());
+ assert(AppendOk && "Could not append filename to directory!");
+ Asm->EmitFile(i, FullPath.toString());
+ Asm->EOL();
+ }
+ }
+
+ // Emit initial sections
+ EmitInitial();
}
}
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
- TAI->getAddressSize() : -TAI->getAddressSize();
+ TD->getPointerSize() : -TD->getPointerSize();
// Begin eh frame section.
Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
if (Personality) {
Asm->EmitULEB128Bytes(7);
Asm->EOL("Augmentation Size");
- Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect);
+
+ if (TAI->getNeedsIndirectEncoding())
+ Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect);
+ else
+ Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4);
+
Asm->EOL("Personality (pcrel sdata4 indirect)");
PrintRelDirective();
// Externally visible entry into the functions eh frame info.
if (const char *GlobalDirective = TAI->getGlobalDirective())
- O << GlobalDirective << EHFrameInfo.FnName << ".eh\n";
+ O << GlobalDirective << EHFrameInfo.FnName << "\n";
// If there are no calls then you can't unwind.
if (!EHFrameInfo.hasCalls) {
- O << EHFrameInfo.FnName << ".eh = 0\n";
+ O << EHFrameInfo.FnName << " = 0\n";
} else {
- O << EHFrameInfo.FnName << ".eh:\n";
+ O << EHFrameInfo.FnName << ":\n";
// EH frame header.
EmitDifference("eh_frame_end", EHFrameInfo.Number,
if (EHFrameInfo.hasLandingPads) {
EmitReference("exception", EHFrameInfo.Number, true);
- } else if(TAI->getAddressSize() == 8) {
+ } else if (TD->getPointerSize() == 8) {
Asm->EmitInt64((int)0);
} else {
Asm->EmitInt32((int)0);
}
if (const char *UsedDirective = TAI->getUsedDirective())
- O << UsedDirective << EHFrameInfo.FnName << ".eh\n\n";
+ O << UsedDirective << EHFrameInfo.FnName << "\n\n";
}
/// EmitExceptionTable - Emit landing pads and actions.
static inline unsigned getEmptyKey() { return -1U; }
static inline unsigned getTombstoneKey() { return -2U; }
static unsigned getHashValue(const unsigned &Key) { return Key; }
+ static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
static bool isPod() { return true; }
};
for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
SizeSites += Asm->SizeULEB128(CallSites[i].Action);
- unsigned SizeTypes = TypeInfos.size() * TAI->getAddressSize();
+ unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
unsigned TypeOffset = sizeof(int8_t) + // Call site format
Asm->SizeULEB128(SizeSites) + // Call-site table length
Asm->EOL("Region length");
if (!S.PadLabel) {
- if (TAI->getAddressSize() == sizeof(int32_t))
+ if (TD->getPointerSize() == sizeof(int32_t))
Asm->EmitInt32(0);
else
Asm->EmitInt64(0);
// Main entry points.
//
DwarfException(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
- : Dwarf(OS, A, T)
+ : Dwarf(OS, A, T, "eh")
, shouldEmit(false)
{}
EmitExceptionTable();
// Save EH frame information
- EHFrames.push_back(FunctionEHFrameInfo(getAsm()->CurrentFnName,
- SubprogramCount,
- MMI->getPersonalityIndex(),
- MF->getFrameInfo()->hasCalls(),
- !MMI->getLandingPads().empty(),
- MMI->getFrameMoves()));
+ EHFrames.
+ push_back(FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF),
+ SubprogramCount,
+ MMI->getPersonalityIndex(),
+ MF->getFrameInfo()->hasCalls(),
+ !MMI->getLandingPads().empty(),
+ MMI->getFrameMoves()));
}
};
/// EmitValue - Emit label value.
///
void DIEDwarfLabel::EmitValue(DwarfDebug &DD, unsigned Form) {
- DD.EmitReference(Label);
+ bool IsSmall = Form == DW_FORM_data4;
+ DD.EmitReference(Label, false, IsSmall);
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEDwarfLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- return DD.getTargetAsmInfo()->getAddressSize();
+ if (Form == DW_FORM_data4) return 4;
+ return DD.getTargetData()->getPointerSize();
}
//===----------------------------------------------------------------------===//
/// EmitValue - Emit label value.
///
void DIEObjectLabel::EmitValue(DwarfDebug &DD, unsigned Form) {
- DD.EmitReference(Label);
+ bool IsSmall = Form == DW_FORM_data4;
+ DD.EmitReference(Label, false, IsSmall);
}
/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEObjectLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- return DD.getTargetAsmInfo()->getAddressSize();
+ if (Form == DW_FORM_data4) return 4;
+ return DD.getTargetData()->getPointerSize();
}
//===----------------------------------------------------------------------===//
///
unsigned DIEDelta::SizeOf(const DwarfDebug &DD, unsigned Form) const {
if (Form == DW_FORM_data4) return 4;
- return DD.getTargetAsmInfo()->getAddressSize();
+ return DD.getTargetData()->getPointerSize();
}
//===----------------------------------------------------------------------===//