2005-12-21 19:48:16 +00:00
|
|
|
//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework ----------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file was developed by James M. Laskey and is distributed under the
|
|
|
|
// University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains support for writing dwarf debug info into asm files.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-01-04 22:28:25 +00:00
|
|
|
#include "llvm/CodeGen/DwarfWriter.h"
|
2005-12-21 19:48:16 +00:00
|
|
|
|
2006-01-04 13:52:30 +00:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
2006-01-04 22:28:25 +00:00
|
|
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
2006-01-04 13:52:30 +00:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
|
2006-01-04 22:28:25 +00:00
|
|
|
#include <iostream>
|
2006-01-04 13:52:30 +00:00
|
|
|
|
2006-01-04 22:28:25 +00:00
|
|
|
using namespace llvm;
|
2006-01-04 13:52:30 +00:00
|
|
|
|
|
|
|
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
|
2006-01-04 22:28:25 +00:00
|
|
|
/// unsigned leb128 value. Comment is added to the end of the directive if
|
|
|
|
/// DwarfVerbose is true (should not contain any newlines.)
|
2006-01-04 13:52:30 +00:00
|
|
|
///
|
2006-01-04 22:28:25 +00:00
|
|
|
void DwarfWriter::EmitULEB128Bytes(unsigned Value, const char *Comment) const {
|
2006-01-04 13:52:30 +00:00
|
|
|
if (hasLEB128) {
|
|
|
|
O << "\t.uleb128\t"
|
|
|
|
<< Value;
|
|
|
|
} else {
|
2006-01-04 22:28:25 +00:00
|
|
|
O << Asm->Data8bitsDirective;
|
2006-01-04 13:52:30 +00:00
|
|
|
EmitULEB128(Value);
|
|
|
|
}
|
|
|
|
if (DwarfVerbose) {
|
|
|
|
O << "\t"
|
2006-01-04 22:28:25 +00:00
|
|
|
<< Asm->CommentString
|
2006-01-04 13:52:30 +00:00
|
|
|
<< " "
|
|
|
|
<< Comment
|
|
|
|
<< " "
|
|
|
|
<< Value;
|
|
|
|
}
|
|
|
|
O << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
|
2006-01-04 22:28:25 +00:00
|
|
|
/// signed leb128 value. Comment is added to the end of the directive if
|
|
|
|
/// DwarfVerbose is true (should not contain any newlines.)
|
2006-01-04 13:52:30 +00:00
|
|
|
///
|
2006-01-04 22:28:25 +00:00
|
|
|
void DwarfWriter::EmitSLEB128Bytes(int Value, const char *Comment) const {
|
2006-01-04 13:52:30 +00:00
|
|
|
if (hasLEB128) {
|
|
|
|
O << "\t.sleb128\t"
|
|
|
|
<< Value;
|
|
|
|
} else {
|
2006-01-04 22:28:25 +00:00
|
|
|
O << Asm->Data8bitsDirective;
|
2006-01-04 13:52:30 +00:00
|
|
|
EmitSLEB128(Value);
|
|
|
|
}
|
|
|
|
if (DwarfVerbose) {
|
|
|
|
O << "\t"
|
2006-01-04 22:28:25 +00:00
|
|
|
<< Asm->CommentString
|
2006-01-04 13:52:30 +00:00
|
|
|
<< " "
|
|
|
|
<< Comment
|
|
|
|
<< " "
|
|
|
|
<< Value;
|
|
|
|
}
|
|
|
|
O << "\n";
|
|
|
|
}
|
|
|
|
|
2006-01-04 22:28:25 +00:00
|
|
|
/// EmitHex - Emit a hexidecimal string to the output stream.
|
2006-01-04 13:52:30 +00:00
|
|
|
///
|
2006-01-04 22:28:25 +00:00
|
|
|
void DwarfWriter::EmitHex(unsigned Value) const {
|
|
|
|
O << "0x"
|
|
|
|
<< std::hex
|
|
|
|
<< Value
|
|
|
|
<< std::dec;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitComment - Emit a simple string comment.
|
|
|
|
///
|
|
|
|
void DwarfWriter::EmitComment(const char *Comment) const {
|
|
|
|
O << "\t"
|
|
|
|
<< Asm->CommentString
|
|
|
|
<< " "
|
|
|
|
<< Comment
|
|
|
|
<< "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
|
|
|
|
/// representing an unsigned leb128 value.
|
|
|
|
///
|
|
|
|
void DwarfWriter::EmitULEB128(unsigned Value) const {
|
|
|
|
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 DwarfWriter::EmitSLEB128(int Value) const {
|
|
|
|
int Sign = Value >> (8 * sizeof(Value) - 1);
|
|
|
|
bool IsMore;
|
2006-01-04 13:52:30 +00:00
|
|
|
|
2006-01-04 22:28:25 +00:00
|
|
|
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 DwarfWriter::EmitLabelName(const char *Tag, int Num) const {
|
|
|
|
O << Asm->PrivateGlobalPrefix
|
|
|
|
<< "debug_"
|
|
|
|
<< Tag
|
|
|
|
<< Num;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitLabel - Emit location label for internal use by dwarf.
|
|
|
|
///
|
|
|
|
void DwarfWriter::EmitLabel(const char *Tag, int Num) const {
|
|
|
|
EmitLabelName(Tag, Num);
|
|
|
|
O << ":\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitInitial -Emit initial dwarf declarations.
|
|
|
|
///
|
|
|
|
void DwarfWriter::EmitInitial() const {
|
|
|
|
// Dwarf section's base addresses.
|
2006-01-04 13:52:30 +00:00
|
|
|
Asm->SwitchSection(DwarfAbbrevSection, 0);
|
|
|
|
EmitLabel("abbrev", 0);
|
|
|
|
Asm->SwitchSection(DwarfInfoSection, 0);
|
|
|
|
EmitLabel("info", 0);
|
|
|
|
Asm->SwitchSection(DwarfLineSection, 0);
|
|
|
|
EmitLabel("line", 0);
|
|
|
|
}
|
|
|
|
|
2006-01-04 22:28:25 +00:00
|
|
|
/// ShouldEmitDwarf - Determine if dwarf declarations should be made.
|
|
|
|
///
|
|
|
|
bool DwarfWriter::ShouldEmitDwarf() {
|
|
|
|
// Check if debug info is present.
|
|
|
|
if (!DebugInfo || !DebugInfo->hasInfo()) return false;
|
|
|
|
|
|
|
|
// Make sure initial declarations are made.
|
|
|
|
if (!didInitial) {
|
|
|
|
EmitInitial();
|
|
|
|
didInitial = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay to emit.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// BeginModule - Emit all dwarf sections that should come prior to the content.
|
|
|
|
///
|
|
|
|
void DwarfWriter::BeginModule() {
|
|
|
|
if (!ShouldEmitDwarf()) return;
|
|
|
|
EmitComment("Dwarf Begin Module");
|
|
|
|
}
|
|
|
|
|
2006-01-04 13:52:30 +00:00
|
|
|
/// EndModule - Emit all dwarf sections that should come after the content.
|
|
|
|
///
|
|
|
|
void DwarfWriter::EndModule() {
|
2006-01-04 22:28:25 +00:00
|
|
|
if (!ShouldEmitDwarf()) return;
|
2006-01-04 13:52:30 +00:00
|
|
|
EmitComment("Dwarf End Module");
|
|
|
|
// Print out dwarf file info
|
2006-01-04 22:28:25 +00:00
|
|
|
std::vector<std::string> Sources = DebugInfo->getSourceFiles();
|
2006-01-04 13:52:30 +00:00
|
|
|
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() {
|
2006-01-04 22:28:25 +00:00
|
|
|
if (!ShouldEmitDwarf()) return;
|
2006-01-04 13:52:30 +00:00
|
|
|
EmitComment("Dwarf Begin Function");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EndFunction - Emit post-function debug information.
|
|
|
|
///
|
|
|
|
void DwarfWriter::EndFunction() {
|
2006-01-04 22:28:25 +00:00
|
|
|
if (!ShouldEmitDwarf()) return;
|
2006-01-04 13:52:30 +00:00
|
|
|
EmitComment("Dwarf End Function");
|
|
|
|
}
|