aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCAssembler.h33
-rw-r--r--include/llvm/MC/MCContext.h4
-rw-r--r--include/llvm/MC/MCDwarf.h68
-rw-r--r--include/llvm/MC/MCObjectWriter.h5
-rw-r--r--include/llvm/MC/MCStreamer.h10
-rw-r--r--include/llvm/Support/Dwarf.h1
6 files changed, 116 insertions, 5 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 8d899d3..d48a0b4 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -49,7 +49,8 @@ public:
FT_Data,
FT_Fill,
FT_Inst,
- FT_Org
+ FT_Org,
+ FT_Dwarf
};
private:
@@ -337,6 +338,36 @@ public:
static bool classof(const MCOrgFragment *) { return true; }
};
+class MCDwarfLineAddrFragment : public MCFragment {
+ /// LineDelta - the value of the difference between the two line numbers
+ /// between two .loc dwarf directives.
+ int64_t LineDelta;
+
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .loc dwarf directives.
+ const MCExpr *AddrDelta;
+
+public:
+ MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
+ MCSectionData *SD = 0)
+ : MCFragment(FT_Dwarf, SD),
+ LineDelta(_LineDelta), AddrDelta(&_AddrDelta) {}
+
+ /// @name Accessors
+ /// @{
+
+ int64_t getLineDelta() const { return LineDelta; }
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Dwarf;
+ }
+ static bool classof(const MCDwarfLineAddrFragment *) { return true; }
+};
+
// FIXME: Should this be a separate class, or just merged into MCSection? Since
// we anticipate the fast path being through an MCAssembler, the only reason to
// keep it out is for API abstraction.
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index d22868c..c2dfb8f 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -162,6 +162,10 @@ namespace llvm {
bool ValidateDwarfFileNumber(unsigned FileNumber);
+ bool hasDwarfFiles(void) {
+ return MCDwarfFiles.size() != 0;
+ }
+
const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
return MCDwarfFiles;
}
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index dac875c..925991e 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -8,8 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the MCDwarfFile to support the dwarf
-// .file directive.
-// TODO: add the support needed for the .loc directive.
+// .file directive and the .loc directive.
//
//===----------------------------------------------------------------------===//
@@ -17,12 +16,18 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Dwarf.h"
#include <vector>
namespace llvm {
class MCContext;
class MCSection;
class MCSymbol;
+ class MCObjectStreamer;
class raw_ostream;
/// MCDwarfFile - Instances of this class represent the name of the dwarf
@@ -79,6 +84,9 @@ namespace llvm {
// Isa
unsigned Isa;
+// Flag that indicates the initial value of the is_stmt_start flag.
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
#define DWARF2_FLAG_IS_STMT (1 << 0)
#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
@@ -95,6 +103,21 @@ namespace llvm {
// for an MCDwarfLoc object.
public:
+ /// getFileNum - Get the FileNum of this MCDwarfLoc.
+ unsigned getFileNum() { return FileNum; }
+
+ /// getLine - Get the Line of this MCDwarfLoc.
+ unsigned getLine() { return Line; }
+
+ /// getColumn - Get the Column of this MCDwarfLoc.
+ unsigned getColumn() { return Column; }
+
+ /// getFlags - Get the Flags of this MCDwarfLoc.
+ unsigned getFlags() { return Flags; }
+
+ /// getIsa - Get the Isa of this MCDwarfLoc.
+ unsigned getIsa() { return Isa; }
+
/// setFileNum - Set the FileNum of this MCDwarfLoc.
void setFileNum(unsigned fileNum) { FileNum = fileNum; }
@@ -127,6 +150,13 @@ namespace llvm {
// Constructor to create an MCLineEntry given a symbol and the dwarf loc.
MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
Label(label) {}
+
+ MCSymbol *getLabel() { return Label; }
+
+ // 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.
+ static void Make(MCObjectStreamer *MCOS, const MCSection *Section);
};
/// MCLineSection - Instances of this class represent the line information
@@ -134,7 +164,6 @@ namespace llvm {
/// .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
@@ -149,8 +178,41 @@ namespace llvm {
void addLineEntry(const MCLineEntry &LineEntry) {
MCLineEntries.push_back(LineEntry);
}
+
+ typedef std::vector<MCLineEntry> MCLineEntryCollection;
+ typedef MCLineEntryCollection::iterator iterator;
+
+ private:
+ MCLineEntryCollection MCLineEntries;
+
+ public:
+ MCLineEntryCollection *getMCLineEntries() { return &MCLineEntries; }
+ };
+
+ class MCDwarfFileTable {
+ public:
+ //
+ // This emits the Dwarf file and the line tables.
+ //
+ static void Emit(MCObjectStreamer *MCOS, const MCSection *DwarfLineSection);
};
+ class MCDwarfLineAddr {
+ public:
+ /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
+ static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
+
+ /// Utility function to emit the encoding to a streamer.
+ static void Emit(MCObjectStreamer *MCOS,
+ int64_t LineDelta,uint64_t AddrDelta);
+
+ /// Utility function to compute the size of the encoding.
+ static uint64_t ComputeSize(int64_t LineDelta, uint64_t AddrDelta);
+
+ /// Utility function to write the encoding to an object writer.
+ static void Write(MCObjectWriter *OW,
+ int64_t LineDelta, uint64_t AddrDelta);
+ };
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 7de37f7..7571583 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -170,6 +170,11 @@ public:
}
/// @}
+
+ /// Utility function to encode a SLEB128 value.
+ static void EncodeSLEB128(int64_t Value, raw_ostream &OS);
+ /// Utility function to encode a ULEB128 value.
+ static void EncodeULEB128(uint64_t Value, raw_ostream &OS);
};
MCObjectWriter *createWinCOFFObjectWriter(raw_ostream &OS, bool is64Bit);
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 0e43ce6..1f4f23d 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -235,10 +235,18 @@ namespace llvm {
virtual void EmitIntValue(uint64_t Value, unsigned Size,
unsigned AddrSpace = 0);
+ /// EmitULEB128Value - Special case of EmitValue that takes an ULEB128 and
+ /// emits the needed bytes for the encoded value.
+ virtual void EmitULEB128Value(uint64_t Value, unsigned AddrSpace = 0);
+
+ /// EmitSLEB128Value - Special case of EmitValue that takes an SLEB128 and
+ /// emits the needed bytes for the encoded value.
+ virtual void EmitSLEB128Value(int64_t Value, unsigned AddrSpace = 0);
+
/// EmitSymbolValue - Special case of EmitValue that avoids the client
/// having to pass in a MCExpr for MCSymbols.
virtual void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
- unsigned AddrSpace);
+ unsigned AddrSpace = 0);
/// EmitGPRel32Value - Emit the expression @p Value into the output as a
/// gprel32 (32-bit GP relative) value.
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index da61dfb..1b5d2a4 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -510,6 +510,7 @@ enum dwarf_constants {
DW_DSC_range = 0x01,
// Line Number Standard Opcode Encodings
+ DW_LNS_extended_op = 0x00,
DW_LNS_copy = 0x01,
DW_LNS_advance_pc = 0x02,
DW_LNS_advance_line = 0x03,