#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);
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
- const std::vector<MachineMove> &Moves) {
+ const std::vector<MachineMove> &Moves, bool isEH) {
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) {
} else {
Asm->EmitInt8(DW_CFA_def_cfa);
Asm->EOL("DW_CFA_def_cfa");
- Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister()));
+ Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister(), isEH));
Asm->EOL("Register");
}
if (Dst.isRegister()) {
Asm->EmitInt8(DW_CFA_def_cfa_register);
Asm->EOL("DW_CFA_def_cfa_register");
- Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister()));
+ Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getRegister(), isEH));
Asm->EOL("Register");
} else {
assert(0 && "Machine move no supported yet.");
}
} else {
- unsigned Reg = RI->getDwarfRegNum(Src.getRegister());
+ unsigned Reg = RI->getDwarfRegNum(Src.getRegister(), isEH);
int Offset = Dst.getOffset() / stackGrowth;
if (Offset < 0) {
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);
/// provided.
void AddAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location) {
- unsigned Reg = RI->getDwarfRegNum(Location.getRegister());
+ unsigned Reg = RI->getDwarfRegNum(Location.getRegister(), false);
DIEBlock *Block = new DIEBlock();
if (Location.isRegister()) {
///
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());
Asm->EOL("CIE Code Alignment Factor");
Asm->EmitSLEB128Bytes(stackGrowth);
Asm->EOL("CIE Data Alignment Factor");
- Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister()));
+ Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
Asm->EOL("CIE RA Column");
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(NULL, 0, Moves);
+ EmitFrameMoves(NULL, 0, Moves, false);
Asm->EmitAlignment(2);
EmitLabel("debug_frame_common_end", 0);
"func_begin", DebugFrameInfo.Number);
Asm->EOL("FDE address range");
- EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves);
+ EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, false);
Asm->EmitAlignment(2);
EmitLabel("debug_frame_end", DebugFrameInfo.Number);
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();
}
}
bool hasCalls;
bool hasLandingPads;
std::vector<MachineMove> Moves;
+ Function::LinkageTypes linkage;
FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P,
bool hC, bool hL,
- const std::vector<MachineMove> &M):
+ const std::vector<MachineMove> &M,
+ Function::LinkageTypes l):
FnName(FN), Number(Num), PersonalityIndex(P),
- hasCalls(hC), hasLandingPads(hL), Moves(M) { }
+ hasCalls(hC), hasLandingPads(hL), Moves(M),
+ linkage(l) { }
};
std::vector<FunctionEHFrameInfo> EHFrames;
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
- TAI->getAddressSize() : -TAI->getAddressSize();
+ TD->getPointerSize() : -TD->getPointerSize();
// Begin eh frame section.
Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
Asm->EOL("CIE Code Alignment Factor");
Asm->EmitSLEB128Bytes(stackGrowth);
Asm->EOL("CIE Data Alignment Factor");
- Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister()));
+ Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
Asm->EOL("CIE RA Column");
// If there is a personality, we need to indicate the functions location.
// Indicate locations of general callee saved registers in frame.
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(NULL, 0, Moves);
+ EmitFrameMoves(NULL, 0, Moves, true);
Asm->EmitAlignment(2);
EmitLabel("eh_frame_common_end", Index);
Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
// Externally visible entry into the functions eh frame info.
- if (const char *GlobalDirective = TAI->getGlobalDirective())
- O << GlobalDirective << EHFrameInfo.FnName << ".eh\n";
-
+ // If the corresponding function is static, this should not be
+ // externally visible.
+ if (EHFrameInfo.linkage != Function::InternalLinkage) {
+ if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
+ O << GlobalEHDirective << 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";
+
+ // If corresponding function is weak definition, this should be too.
+ if ((EHFrameInfo.linkage == Function::WeakLinkage ||
+ EHFrameInfo.linkage == Function::LinkOnceLinkage) &&
+ TAI->getWeakDefDirective())
+ O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n";
+
// EH frame header.
EmitDifference("eh_frame_end", EHFrameInfo.Number,
"eh_frame_begin", EHFrameInfo.Number, true);
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);
// Indicate locations of function specific callee saved registers in
// frame.
- EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves);
+ EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, true);
Asm->EmitAlignment(2);
EmitLabel("eh_frame_end", EHFrameInfo.Number);
}
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(),
+ MF->getFunction()->getLinkage()));
}
};
/// 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();
}
//===----------------------------------------------------------------------===//