mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-25 17:20:48 +00:00
Tie dwarf generation to darwin assembler.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25093 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -35,7 +35,7 @@ namespace llvm {
|
|||||||
/// IncrementFunctionNumber().
|
/// IncrementFunctionNumber().
|
||||||
///
|
///
|
||||||
unsigned FunctionNumber;
|
unsigned FunctionNumber;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Output stream on which we're printing assembly code.
|
/// Output stream on which we're printing assembly code.
|
||||||
///
|
///
|
||||||
@@ -165,6 +165,7 @@ namespace llvm {
|
|||||||
|
|
||||||
AsmPrinter(std::ostream &o, TargetMachine &TM);
|
AsmPrinter(std::ostream &o, TargetMachine &TM);
|
||||||
|
|
||||||
|
public:
|
||||||
/// SwitchSection - Switch to the specified section of the executable if we
|
/// 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
|
/// 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
|
/// 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);
|
void SwitchSection(const char *NewSection, const GlobalValue *GV);
|
||||||
|
|
||||||
|
protected:
|
||||||
/// getFunctionNumber - Return a unique ID for the current function.
|
/// getFunctionNumber - Return a unique ID for the current function.
|
||||||
///
|
///
|
||||||
unsigned getFunctionNumber() const { return FunctionNumber; }
|
unsigned getFunctionNumber() const { return FunctionNumber; }
|
||||||
@@ -229,6 +231,43 @@ namespace llvm {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void EmitXXStructorList(Constant *List);
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,11 +14,14 @@
|
|||||||
#ifndef LLVM_CODEGEN_DWARFPRINTER_H
|
#ifndef LLVM_CODEGEN_DWARFPRINTER_H
|
||||||
#define LLVM_CODEGEN_DWARFPRINTER_H
|
#define LLVM_CODEGEN_DWARFPRINTER_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
|
// 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 {
|
enum dwarf_constants {
|
||||||
// Tags
|
// Tags
|
||||||
@@ -422,6 +425,141 @@ namespace llvm {
|
|||||||
DW_CFA_lo_user = 0x1c,
|
DW_CFA_lo_user = 0x1c,
|
||||||
DW_CFA_hi_user = 0x3f
|
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
|
} // end llvm namespace
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||||
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
#include "llvm/Support/Mangler.h"
|
#include "llvm/Support/Mangler.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
@@ -12,4 +12,99 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
#include "llvm/CodeGen/DwarfWriter.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
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
|
#include "llvm/CodeGen/DwarfWriter.h"
|
||||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
@@ -205,13 +206,33 @@ namespace {
|
|||||||
virtual bool doFinalization(Module &M) = 0;
|
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
|
/// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
|
||||||
/// X
|
/// X
|
||||||
///
|
///
|
||||||
struct DarwinAsmPrinter : public PPCAsmPrinter {
|
struct DarwinAsmPrinter : public PPCAsmPrinter {
|
||||||
|
|
||||||
|
DarwinDwarfWriter DW;
|
||||||
|
|
||||||
DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
|
DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
|
||||||
: PPCAsmPrinter(O, TM) {
|
: PPCAsmPrinter(O, TM),
|
||||||
|
// FIXME - MachineDebugInfo needs a proper location
|
||||||
|
DW(O, this, getMachineDebugInfo())
|
||||||
|
{
|
||||||
CommentString = ";";
|
CommentString = ";";
|
||||||
GlobalPrefix = "_";
|
GlobalPrefix = "_";
|
||||||
PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
|
PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
|
||||||
@@ -397,12 +418,8 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
SetupMachineFunction(MF);
|
SetupMachineFunction(MF);
|
||||||
O << "\n\n";
|
O << "\n\n";
|
||||||
|
|
||||||
// Print out dwarf file info
|
// Emit pre-function debug information.
|
||||||
MachineDebugInfo &DebugInfo = MF.getDebugInfo();
|
DW.BeginFunction();
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print out constants referenced by the function
|
// Print out constants referenced by the function
|
||||||
EmitConstantPool(MF.getConstantPool());
|
EmitConstantPool(MF.getConstantPool());
|
||||||
@@ -449,6 +466,9 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit post-function debug information.
|
||||||
|
DW.EndFunction();
|
||||||
|
|
||||||
// We didn't modify anything.
|
// We didn't modify anything.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -461,6 +481,9 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
|
|||||||
|
|
||||||
// Darwin wants symbols to be quoted if they have complex names.
|
// Darwin wants symbols to be quoted if they have complex names.
|
||||||
Mang->setUseQuotes(true);
|
Mang->setUseQuotes(true);
|
||||||
|
|
||||||
|
// Emit initial debug information.
|
||||||
|
DW.BeginModule();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,6 +606,9 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
|
|||||||
// code that does this, it is always safe to set.
|
// code that does this, it is always safe to set.
|
||||||
O << "\t.subsections_via_symbols\n";
|
O << "\t.subsections_via_symbols\n";
|
||||||
|
|
||||||
|
// Emit initial debug information.
|
||||||
|
DW.EndModule();
|
||||||
|
|
||||||
AsmPrinter::doFinalization(M);
|
AsmPrinter::doFinalization(M);
|
||||||
return false; // success
|
return false; // success
|
||||||
}
|
}
|
||||||
@@ -592,7 +618,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
|
|||||||
///
|
///
|
||||||
bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||||
SetupMachineFunction(MF);
|
SetupMachineFunction(MF);
|
||||||
|
|
||||||
// Print out constants referenced by the function
|
// Print out constants referenced by the function
|
||||||
EmitConstantPool(MF.getConstantPool());
|
EmitConstantPool(MF.getConstantPool());
|
||||||
|
|
||||||
|
@@ -80,7 +80,7 @@ bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM,
|
|||||||
CodeGenFileType FileType,
|
CodeGenFileType FileType,
|
||||||
bool Fast) {
|
bool Fast) {
|
||||||
if (FileType != TargetMachine::AssemblyFile) return true;
|
if (FileType != TargetMachine::AssemblyFile) return true;
|
||||||
|
|
||||||
// Run loop strength reduction before anything else.
|
// Run loop strength reduction before anything else.
|
||||||
if (!Fast) PM.add(createLoopStrengthReducePass());
|
if (!Fast) PM.add(createLoopStrengthReducePass());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user