Tie dwarf generation to darwin assembler.

llvm-svn: 25093
This commit is contained in:
Jim Laskey 2006-01-04 13:52:30 +00:00
parent 1e8731ef60
commit b0609d91c3
6 changed files with 311 additions and 12 deletions

View File

@ -165,6 +165,7 @@ namespace llvm {
AsmPrinter(std::ostream &o, TargetMachine &TM);
public:
/// SwitchSection - Switch to the specified section of the executable if we
/// are not already in it! If GV is non-null and if the global has an
/// explicitly requested section, we switch to the section indicated for the
@ -175,6 +176,7 @@ namespace llvm {
///
void SwitchSection(const char *NewSection, const GlobalValue *GV);
protected:
/// getFunctionNumber - Return a unique ID for the current function.
///
unsigned getFunctionNumber() const { return FunctionNumber; }
@ -229,6 +231,43 @@ namespace llvm {
private:
void EmitXXStructorList(Constant *List);
public:
/// getCommentString - get the comment string.
///
const char *getCommentString() {
return CommentString;
}
/// getData8bitsDirective - get the 8-bit data directive string.
///
const char *getData8bitsDirective() {
return Data8bitsDirective;
}
/// getData16bitsDirective - get the 16-bit data directive string.
///
const char *getData16bitsDirective() {
return Data16bitsDirective;
}
/// getData32bitsDirective - get the 32-bit data directive string.
///
const char *getData32bitsDirective() {
return Data32bitsDirective;
}
/// getData64bitsDirective - get the 64-bit data directive string.
///
const char *getData64bitsDirective() {
return Data64bitsDirective;
}
/// getPrivateGlobalPrefix - get private label prefix.
///
const char *getPrivateGlobalPrefix() {
return PrivateGlobalPrefix;
}
};
}

View File

@ -14,11 +14,14 @@
#ifndef LLVM_CODEGEN_DWARFPRINTER_H
#define LLVM_CODEGEN_DWARFPRINTER_H
#include <iostream>
#include "llvm/CodeGen/MachineDebugInfo.h"
namespace llvm {
//===----------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
// reference manual http://dwarf.freestandards.org.
// reference manual http://dwarf.freestandards.org .
//
enum dwarf_constants {
// Tags
@ -423,6 +426,141 @@ namespace llvm {
DW_CFA_hi_user = 0x3f
};
// Forward declarations.
//
class AsmPrinter;
//===--------------------------------------------------------------------===//
// DwarfWriter - emits dwarf debug and exception handling directives.
//
class DwarfWriter {
protected:
/// O - Stream to .s file.
///
std::ostream &O;
/// Asm - Target of dwarf emission.
///
AsmPrinter *Asm;
/// DebugInfo - Collected debug information.
///
MachineDebugInfo &DebugInfo;
/// hasLEB128 - True if target asm supports leb128 directives.
///
bool hasLEB128; /// Defaults to false.
/// needsSet - True if target asm can't compute addresses on data
/// directives.
bool needsSet; /// Defaults to false.
/// DwarfAbbrevSection - section directive arg for dwarf abbrev.
///
const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev".
/// DwarfInfoSection - section directive arg for dwarf info.
///
const char *DwarfInfoSection; /// Defaults to ".debug_info".
/// DwarfLineSection - section directive arg for dwarf info.
///
const char *DwarfLineSection; /// Defaults to ".debug_line".
public:
// Ctor.
DwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di)
: O(o)
, Asm(ap)
, DebugInfo(di)
, hasLEB128(false)
, needsSet(false)
, DwarfAbbrevSection(".debug_abbrev")
, DwarfInfoSection(".debug_info")
, DwarfLineSection(".debug_line")
{}
/// EmitHex - Emit a hexidecimal string to the output stream.
///
void EmitHex(unsigned Value) {
O << "0x"
<< std::hex
<< Value
<< std::dec;
}
/// EmitComment - Emit a simple string comment.
///
void EmitComment(const char *Comment) {
O << "\t"
<< Asm->getCommentString()
<< " "
<< Comment
<< "\n";
}
/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
/// representing an unsigned leb128 value.
///
void EmitULEB128(unsigned Value) {
do {
unsigned Byte = Value & 0x7f;
Value >>= 7;
if (Value) Byte |= 0x80;
EmitHex(Byte);
if (Value) O << ", ";
} while (Value);
}
/// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas)
/// representing a signed leb128 value.
///
void EmitSLEB128(int Value) {
int Sign = Value >> (8 * sizeof(Value) - 1);
bool IsMore;
do {
unsigned Byte = Value & 0x7f;
Value >>= 7;
IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
if (IsMore) Byte |= 0x80;
EmitHex(Byte);
if (IsMore) O << ", ";
} while (IsMore);
}
/// EmitLabelName - Emit label name for internal use by dwarf.
///
void EmitLabelName(const char *Tag, int Num) {
O << Asm->getPrivateGlobalPrefix()
<< "debug_"
<< Tag
<< Num;
}
/// EmitLabel - Emit location label for internal use by dwarf.
///
void EmitLabel(const char *Tag, int Num) {
EmitLabelName(Tag, Num);
O << ":\n";
}
// Defined elsewhere
void EmitULEB128Bytes(unsigned Value, std::string Comment);
void EmitSLEB128Bytes(int Value, std::string Comment);
void BeginModule();
void EndModule();
void BeginFunction();
void EndFunction();
};
} // end llvm namespace
#endif

View File

@ -16,6 +16,7 @@
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetMachine.h"

View File

@ -12,4 +12,99 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Support/CommandLine.h"
namespace llvm {
static cl::opt<bool>
DwarfVerbose("dwarf-verbose", cl::Hidden,
cl::desc("Add comments to dwarf directives."));
/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
/// unsigned leb128 value.
///
void DwarfWriter::EmitULEB128Bytes(unsigned Value, std::string Comment) {
if (hasLEB128) {
O << "\t.uleb128\t"
<< Value;
} else {
O << Asm->getData8bitsDirective();
EmitULEB128(Value);
}
if (DwarfVerbose) {
O << "\t"
<< Asm->getCommentString()
<< " "
<< Comment
<< " "
<< Value;
}
O << "\n";
}
/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
/// signed leb128 value.
///
void DwarfWriter::EmitSLEB128Bytes(int Value, std::string Comment) {
if (hasLEB128) {
O << "\t.sleb128\t"
<< Value;
} else {
O << Asm->getData8bitsDirective();
EmitSLEB128(Value);
}
if (DwarfVerbose) {
O << "\t"
<< Asm->getCommentString()
<< " "
<< Comment
<< " "
<< Value;
}
O << "\n";
}
/// BeginModule - Emit all dwarf sections that should come prior to the content.
///
void DwarfWriter::BeginModule() {
EmitComment("Dwarf Begin Module");
// define base addresses for dwarf sections
Asm->SwitchSection(DwarfAbbrevSection, 0);
EmitLabel("abbrev", 0);
Asm->SwitchSection(DwarfInfoSection, 0);
EmitLabel("info", 0);
Asm->SwitchSection(DwarfLineSection, 0);
EmitLabel("line", 0);
}
/// EndModule - Emit all dwarf sections that should come after the content.
///
void DwarfWriter::EndModule() {
EmitComment("Dwarf End Module");
// Print out dwarf file info
std::vector<std::string> Sources = DebugInfo.getSourceFiles();
for (unsigned i = 0, N = Sources.size(); i < N; i++) {
O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n";
}
}
/// BeginFunction - Emit pre-function debug information.
///
void DwarfWriter::BeginFunction() {
EmitComment("Dwarf Begin Function");
}
/// EndFunction - Emit post-function debug information.
///
void DwarfWriter::EndFunction() {
EmitComment("Dwarf End Function");
}
} // End llvm namespace

View File

@ -25,6 +25,7 @@
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
@ -205,13 +206,33 @@ namespace {
virtual bool doFinalization(Module &M) = 0;
};
/// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
///
struct DarwinDwarfWriter : public DwarfWriter {
// Ctor.
DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap, MachineDebugInfo &di)
: DwarfWriter(o, ap, di)
{
hasLEB128 = false;
needsSet = true;
DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev,regular,debug";
DwarfInfoSection = ".section __DWARFA,__debug_info,regular,debug";
DwarfLineSection = ".section __DWARFA,__debug_line,regular,debug";
}
};
/// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
/// X
///
struct DarwinAsmPrinter : public PPCAsmPrinter {
DarwinDwarfWriter DW;
DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
: PPCAsmPrinter(O, TM) {
: PPCAsmPrinter(O, TM),
// FIXME - MachineDebugInfo needs a proper location
DW(O, this, getMachineDebugInfo())
{
CommentString = ";";
GlobalPrefix = "_";
PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
@ -397,12 +418,8 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
SetupMachineFunction(MF);
O << "\n\n";
// Print out dwarf file info
MachineDebugInfo &DebugInfo = MF.getDebugInfo();
std::vector<std::string> Sources = DebugInfo.getSourceFiles();
for (unsigned i = 0, N = Sources.size(); i < N; i++) {
O << "\t; .file\t" << (i + 1) << "," << "\"" << Sources[i] << "\"" << "\n";
}
// Emit pre-function debug information.
DW.BeginFunction();
// Print out constants referenced by the function
EmitConstantPool(MF.getConstantPool());
@ -449,6 +466,9 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
// Emit post-function debug information.
DW.EndFunction();
// We didn't modify anything.
return false;
}
@ -461,6 +481,9 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
// Darwin wants symbols to be quoted if they have complex names.
Mang->setUseQuotes(true);
// Emit initial debug information.
DW.BeginModule();
return false;
}
@ -583,6 +606,9 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
// code that does this, it is always safe to set.
O << "\t.subsections_via_symbols\n";
// Emit initial debug information.
DW.EndModule();
AsmPrinter::doFinalization(M);
return false; // success
}