aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCContext.h12
-rw-r--r--include/llvm/MC/MCDwarf.h58
-rw-r--r--lib/MC/MCContext.cpp2
-rw-r--r--lib/MC/MCMachOStreamer.cpp56
4 files changed, 121 insertions, 7 deletions
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 6686950b72..d22868cdbd 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -26,6 +26,7 @@ namespace llvm {
class MCLabel;
class MCDwarfFile;
class MCDwarfLoc;
+ class MCLineSection;
class StringRef;
class Twine;
class MCSectionMachO;
@@ -75,6 +76,10 @@ namespace llvm {
MCDwarfLoc CurrentDwarfLoc;
bool DwarfLocSeen;
+ /// The dwarf line information from the .loc directives for the sections
+ /// with assembled machine instructions have after seeing .loc directives.
+ DenseMap<const MCSection *, MCLineSection *> MCLineSections;
+
/// Allocator - Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
@@ -163,6 +168,9 @@ namespace llvm {
const std::vector<StringRef> &getMCDwarfDirs() {
return MCDwarfDirs;
}
+ DenseMap<const MCSection *, MCLineSection *> &getMCLineSections() {
+ return MCLineSections;
+ }
/// setCurrentDwarfLoc - saves the information from the currently parsed
/// dwarf .loc directive and sets DwarfLocSeen. When the next instruction /// is assembled an entry in the line number table with this information and
@@ -176,6 +184,10 @@ namespace llvm {
CurrentDwarfLoc.setIsa(Isa);
DwarfLocSeen = true;
}
+ void clearDwarfLocSeen() { DwarfLocSeen = false; }
+
+ bool getDwarfLocSeen() { return DwarfLocSeen; }
+ const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
/// @}
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 4f39f79397..99a341f507 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -17,9 +17,12 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
+#include <vector>
namespace llvm {
class MCContext;
+ class MCSection;
+ class MCSymbol;
class raw_ostream;
/// MCDwarfFile - Instances of this class represent the name of the dwarf
@@ -57,6 +60,11 @@ namespace llvm {
void dump() const;
};
+ inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
+ DwarfFile.print(OS);
+ return OS;
+ }
+
/// MCDwarfLoc - Instances of this class represent the information from a
/// dwarf .loc directive.
class MCDwarfLoc {
@@ -78,12 +86,14 @@ namespace llvm {
private: // MCContext manages these
friend class MCContext;
+ friend class MCLineEntry;
MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
unsigned isa)
: FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa) {}
- MCDwarfLoc(const MCDwarfLoc&); // DO NOT IMPLEMENT
- void operator=(const MCDwarfLoc&); // DO NOT IMPLEMENT
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCDwarfLoc object.
+
public:
/// setFileNum - Set the FileNum of this MCDwarfLoc.
void setFileNum(unsigned fileNum) { FileNum = fileNum; }
@@ -101,10 +111,46 @@ namespace llvm {
void setIsa(unsigned isa) { Isa = isa; }
};
- inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
- DwarfFile.print(OS);
- return OS;
- }
+ /// MCLineEntry - Instances of this class represent the line information for
+ /// the dwarf line table entries. Which is created after a machine
+ /// instruction is assembled and uses an address from a temporary label
+ /// created at the current address in the current section and the info from
+ /// the last .loc directive seen as stored in the context.
+ class MCLineEntry : public MCDwarfLoc {
+ MCSymbol *Label;
+
+ private:
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCLineEntry object.
+
+ public:
+ // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
+ MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
+ Label(label) {}
+ };
+
+ /// MCLineSection - Instances of this class represent the line information
+ /// for a section where machine instructions have been assembled after seeing
+ /// .loc directives. This is the information used to build the dwarf line
+ /// table for a section.
+ class MCLineSection {
+ std::vector<MCLineEntry> MCLineEntries;
+
+ private:
+ MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT
+ void operator=(const MCLineSection&); // DO NOT IMPLEMENT
+
+ public:
+ // Constructor to create an MCLineSection with an empty MCLineEntries
+ // vector.
+ MCLineSection(): MCLineEntries() {};
+
+ // addLineEntry - adds an entry to this MCLineSection's line entries
+ void addLineEntry(const MCLineEntry &LineEntry) {
+ MCLineEntries.push_back(LineEntry);
+ }
+ };
+
} // end namespace llvm
#endif
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 13cf9a8048..e5586a0d7c 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -227,7 +227,7 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
Name = Slash.second;
for (DirIndex = 0; DirIndex < MCDwarfDirs.size(); DirIndex++) {
if (Directory == MCDwarfDirs[DirIndex])
- break;
+ break;
}
if (DirIndex >= MCDwarfDirs.size()) {
char *Buf = static_cast<char *>(Allocate(Directory.size()));
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 88d9982bd2..639aa27fce 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -33,6 +33,7 @@ private:
void EmitInstToFragment(const MCInst &Inst);
void EmitInstToData(const MCInst &Inst);
// FIXME: These will likely moved to a better place.
+ void MakeLineEntryForSection(const MCSection *Section);
const MCExpr * MakeStartMinusEndExpr(MCSymbol *Start, MCSymbol *End,
int IntVal);
void EmitDwarfFileTable(void);
@@ -409,6 +410,10 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
getCurrentSectionData()->setHasInstructions(true);
+ // Now that a machine instruction has been assembled into this section, make
+ // a line entry for any .loc directive that has been seen.
+ MakeLineEntryForSection(getCurrentSection());
+
// If this instruction doesn't need relaxation, just emit it as data.
if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
EmitInstToData(Inst);
@@ -431,6 +436,47 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
}
//
+// This is called when an instruction is assembled into the specified section
+// and if there is information from the last .loc directive that has yet to have
+// a line entry made for it is made.
+//
+void MCMachOStreamer::MakeLineEntryForSection(const MCSection *Section) {
+ if (!getContext().getDwarfLocSeen())
+ return;
+
+ // Create a symbol at in the current section for use in the line entry.
+ MCSymbol *LineSym = getContext().CreateTempSymbol();
+ // Set the value of the symbol to use for the MCLineEntry.
+ EmitLabel(LineSym);
+
+ // Get the current .loc info saved in the context.
+ const MCDwarfLoc &DwarfLoc = getContext().getCurrentDwarfLoc();
+
+ // Create a (local) line entry with the symbol and the current .loc info.
+ MCLineEntry LineEntry(LineSym, DwarfLoc);
+
+ // clear DwarfLocSeen saying the current .loc info is now used.
+ getContext().clearDwarfLocSeen();
+
+ // Get the MCLineSection for this section, if one does not exist for this
+ // section create it.
+ DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
+ getContext().getMCLineSections();
+ MCLineSection *LineSection = MCLineSections[Section];
+ if (!LineSection) {
+ // Create a new MCLineSection. This will be deleted after the dwarf line
+ // table is created using it by iterating through the MCLineSections
+ // DenseMap.
+ LineSection = new MCLineSection;
+ // Save a pointer to the new LineSection into the MCLineSections DenseMap.
+ MCLineSections[Section] = LineSection;
+ }
+
+ // Add the line entry to this section's entries.
+ LineSection->addLineEntry(LineEntry);
+}
+
+//
// This helper routine returns an expression of End - Start + IntVal for use
// by EmitDwarfFileTable() below.
//
@@ -552,6 +598,16 @@ void MCMachOStreamer::EmitDwarfFileTable(void) {
// TODO: This is the point where the line tables would be emitted.
+ // Delete the MCLineSections that were created in
+ // MCMachOStreamer::MakeLineEntryForSection() and used to emit the line
+ // tables.
+ DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
+ getContext().getMCLineSections();
+ for (DenseMap<const MCSection *, MCLineSection *>::iterator it =
+ MCLineSections.begin(), ie = MCLineSections.end(); it != ie; ++it) {
+ delete it->second;
+ }
+
// If there are no line tables emited then we emit:
// The following DW_LNE_set_address sequence to set the address to zero
// TODO test for 32-bit or 64-bit output