Add and sort "sections" in debug lines. This always stepping through

code in sections other than ".text", including weak sections like ctors and
dtors.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28909 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-06-23 12:51:53 +00:00
parent 52b510b4c4
commit 89d67faf30
6 changed files with 132 additions and 114 deletions

View File

@ -26,10 +26,6 @@ namespace llvm {
class GlobalVariable; class GlobalVariable;
class AsmPrinter : public MachineFunctionPass { class AsmPrinter : public MachineFunctionPass {
/// CurrentSection - The current section we are emitting to. This is
/// controlled and used by the SwitchSection method.
std::string CurrentSection;
/// FunctionNumber - This provides a unique ID for each function emitted in /// FunctionNumber - This provides a unique ID for each function emitted in
/// this translation unit. It is autoincremented by SetupMachineFunction, /// this translation unit. It is autoincremented by SetupMachineFunction,
/// and can be accessed with getFunctionNumber() and /// and can be accessed with getFunctionNumber() and
@ -134,6 +130,10 @@ namespace llvm {
//===--- Section Switching Directives ---------------------------------===// //===--- Section Switching Directives ---------------------------------===//
/// CurrentSection - The current section we are emitting to. This is
/// controlled and used by the SwitchSection method.
std::string CurrentSection;
/// SwitchToSectionDirective - This is the directive used when we want to /// SwitchToSectionDirective - This is the directive used when we want to
/// emit a global to an arbitrary section. The section name is emited after /// emit a global to an arbitrary section. The section name is emited after
/// this. /// this.

View File

@ -47,6 +47,7 @@ class MachineMove;
class Module; class Module;
class MRegisterInfo; class MRegisterInfo;
class SubprogramDesc; class SubprogramDesc;
class SourceLineInfo;
class TargetData; class TargetData;
class Type; class Type;
class TypeDesc; class TypeDesc;
@ -110,11 +111,6 @@ protected:
/// ///
bool shouldEmit; bool shouldEmit;
/// IsNormalText - Flag to indicate if routine is not special case text
/// (coalesced.)
// FIXME - should be able to debug coalesced functions.
bool IsNormalText;
/// SubprogramCount - The running count of functions being compiled. /// SubprogramCount - The running count of functions being compiled.
/// ///
unsigned SubprogramCount; unsigned SubprogramCount;
@ -144,10 +140,13 @@ protected:
/// descriptors to debug information entries. /// descriptors to debug information entries.
std::map<DebugInfoDesc *, DIE *> DescToDieMap; std::map<DebugInfoDesc *, DIE *> DescToDieMap;
/// TypeToDieMap - Type to DIEType map. /// SectionMap - Provides a unique id per text section.
/// ///
// FIXME - Should not be needed. UniqueVector<std::string> SectionMap;
std::map<Type *, DIE *> TypeToDieMap;
/// SectionSourceLines - Tracks line numbers per text section.
///
std::vector<std::vector<SourceLineInfo *> > SectionSourceLines;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Properties to be set by the derived class ctor, used to configure the // Properties to be set by the derived class ctor, used to configure the
@ -483,7 +482,7 @@ public:
/// BeginFunction - Gather pre-function debug information. Assumes being /// BeginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point. /// emitted immediately after the function entry point.
void BeginFunction(MachineFunction *MF, bool IsNormalText); void BeginFunction(MachineFunction *MF);
/// EndFunction - Gather and emit post-function debug information. /// EndFunction - Gather and emit post-function debug information.
/// ///

View File

@ -1031,9 +1031,9 @@ public:
return SourceFiles; return SourceFiles;
} }
/// getSourceLines - Return a vector of source lines. Vector index + 1 /// getSourceLines - Return a vector of source lines.
/// equals label ID. ///
const std::vector<SourceLineInfo *> &getSourceLines() const { std::vector<SourceLineInfo *> &getSourceLines() {
return Lines; return Lines;
} }

View File

@ -1446,8 +1446,8 @@ CompileUnit *DwarfWriter::NewCompileUnit(CompileUnitDesc *UnitDesc,
DIE *Die = new DIE(DW_TAG_compile_unit); DIE *Die = new DIE(DW_TAG_compile_unit);
Die->AddDelta (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0), Die->AddDelta (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0),
DWLabel("section_line", 0)); DWLabel("section_line", 0));
Die->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0)); // Die->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0));
Die->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0)); // Die->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0));
Die->AddString(DW_AT_producer, DW_FORM_string, UnitDesc->getProducer()); Die->AddString(DW_AT_producer, DW_FORM_string, UnitDesc->getProducer());
Die->AddUInt (DW_AT_language, DW_FORM_data1, UnitDesc->getLanguage()); Die->AddUInt (DW_AT_language, DW_FORM_data1, UnitDesc->getLanguage());
Die->AddString(DW_AT_name, DW_FORM_string, UnitDesc->getFileName()); Die->AddString(DW_AT_name, DW_FORM_string, UnitDesc->getFileName());
@ -1702,11 +1702,11 @@ void DwarfWriter::EmitInitial() {
Asm->SwitchToDataSection(DwarfRangesSection, 0); Asm->SwitchToDataSection(DwarfRangesSection, 0);
EmitLabel("section_ranges", 0); EmitLabel("section_ranges", 0);
Asm->SwitchToDataSection(TextSection, 0); Asm->SwitchToTextSection(TextSection, 0);
EmitLabel("text_begin", 0); EmitLabel("text_begin", 0);
Asm->SwitchToDataSection(DataSection, 0); Asm->SwitchToDataSection(DataSection, 0);
EmitLabel("data_begin", 0); EmitLabel("data_begin", 0);
// Emit common frame information. // Emit common frame information.
EmitInitialDebugFrame(); EmitInitialDebugFrame();
} }
@ -2011,76 +2011,86 @@ void DwarfWriter::EmitDebugLines() const {
EmitLabel("line_prolog_end", 0); EmitLabel("line_prolog_end", 0);
// Emit line information // A sequence for each text section.
const std::vector<SourceLineInfo *> &LineInfos = DebugInfo->getSourceLines(); for (unsigned j = 0, M = SectionSourceLines.size(); j < M; ++j) {
// Isolate current sections line info.
// Dwarf assumes we start with first line of first source file. const std::vector<SourceLineInfo *> &LineInfos = SectionSourceLines[j];
unsigned Source = 1;
unsigned Line = 1;
// Construct rows of the address, source, line, column matrix.
for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
SourceLineInfo *LineInfo = LineInfos[i];
if (DwarfVerbose) { if (DwarfVerbose) {
unsigned SourceID = LineInfo->getSourceID();
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
unsigned DirectoryID = SourceFile.getDirectoryID();
O << "\t" O << "\t"
<< Asm->CommentString << " " << Asm->CommentString << " "
<< Directories[DirectoryID] << "Section "
<< SourceFile.getName() << ":" << SectionMap[j + 1].c_str() << "\n";
<< LineInfo->getLine() << "\n";
} }
// Define the line address. // Dwarf assumes we start with first line of first source file.
unsigned Source = 1;
unsigned Line = 1;
// Construct rows of the address, source, line, column matrix.
for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
SourceLineInfo *LineInfo = LineInfos[i];
if (DwarfVerbose) {
unsigned SourceID = LineInfo->getSourceID();
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
unsigned DirectoryID = SourceFile.getDirectoryID();
O << "\t"
<< Asm->CommentString << " "
<< Directories[DirectoryID]
<< SourceFile.getName() << ":"
<< LineInfo->getLine() << "\n";
}
// Define the line address.
EmitInt8(0); EOL("Extended Op");
EmitInt8(4 + 1); EOL("Op size");
EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address");
EmitReference("loc", LineInfo->getLabelID()); EOL("Location label");
// If change of source, then switch to the new source.
if (Source != LineInfo->getSourceID()) {
Source = LineInfo->getSourceID();
EmitInt8(DW_LNS_set_file); EOL("DW_LNS_set_file");
EmitULEB128Bytes(Source); EOL("New Source");
}
// If change of line.
if (Line != LineInfo->getLine()) {
// Determine offset.
int Offset = LineInfo->getLine() - Line;
int Delta = Offset - MinLineDelta;
// Update line.
Line = LineInfo->getLine();
// If delta is small enough and in range...
if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
// ... then use fast opcode.
EmitInt8(Delta - MinLineDelta); EOL("Line Delta");
} else {
// ... otherwise use long hand.
EmitInt8(DW_LNS_advance_line); EOL("DW_LNS_advance_line");
EmitSLEB128Bytes(Offset); EOL("Line Offset");
EmitInt8(DW_LNS_copy); EOL("DW_LNS_copy");
}
} else {
// Copy the previous row (different address or source)
EmitInt8(DW_LNS_copy); EOL("DW_LNS_copy");
}
}
// Define last address of section.
EmitInt8(0); EOL("Extended Op"); EmitInt8(0); EOL("Extended Op");
EmitInt8(4 + 1); EOL("Op size"); EmitInt8(4 + 1); EOL("Op size");
EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address"); EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address");
EmitReference("loc", LineInfo->getLabelID()); EOL("Location label"); EmitReference("section_end", j + 1); EOL("Section end label");
// If change of source, then switch to the new source. // Mark end of matrix.
if (Source != LineInfo->getSourceID()) { EmitInt8(0); EOL("DW_LNE_end_sequence");
Source = LineInfo->getSourceID(); EmitULEB128Bytes(1); O << "\n";
EmitInt8(DW_LNS_set_file); EOL("DW_LNS_set_file"); EmitInt8(1); O << "\n";
EmitULEB128Bytes(Source); EOL("New Source");
}
// If change of line.
if (Line != LineInfo->getLine()) {
// Determine offset.
int Offset = LineInfo->getLine() - Line;
int Delta = Offset - MinLineDelta;
// Update line.
Line = LineInfo->getLine();
// If delta is small enough and in range...
if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
// ... then use fast opcode.
EmitInt8(Delta - MinLineDelta); EOL("Line Delta");
} else {
// ... otherwise use long hand.
EmitInt8(DW_LNS_advance_line); EOL("DW_LNS_advance_line");
EmitSLEB128Bytes(Offset); EOL("Line Offset");
EmitInt8(DW_LNS_copy); EOL("DW_LNS_copy");
}
} else {
// Copy the previous row (different address or source)
EmitInt8(DW_LNS_copy); EOL("DW_LNS_copy");
}
} }
// Define last address.
EmitInt8(0); EOL("Extended Op");
EmitInt8(4 + 1); EOL("Op size");
EmitInt8(DW_LNE_set_address); EOL("DW_LNE_set_address");
EmitReference("text_end", 0); EOL("Location label");
// Mark end of matrix.
EmitInt8(0); EOL("DW_LNE_end_sequence");
EmitULEB128Bytes(1); O << "\n";
EmitInt8(1); O << "\n";
EmitLabel("line_end", 0); EmitLabel("line_end", 0);
@ -2336,14 +2346,14 @@ DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
, DebugInfo(NULL) , DebugInfo(NULL)
, didInitial(false) , didInitial(false)
, shouldEmit(false) , shouldEmit(false)
, IsNormalText(false)
, SubprogramCount(0) , SubprogramCount(0)
, CompileUnits() , CompileUnits()
, Abbreviations() , Abbreviations()
, StringPool() , StringPool()
, DescToUnitMap() , DescToUnitMap()
, DescToDieMap() , DescToDieMap()
, TypeToDieMap() , SectionMap()
, SectionSourceLines()
, AddressSize(sizeof(int32_t)) , AddressSize(sizeof(int32_t))
, hasLEB128(false) , hasLEB128(false)
, hasDotLoc(false) , hasDotLoc(false)
@ -2388,6 +2398,9 @@ void DwarfWriter::SetDebugInfo(MachineDebugInfo *DI) {
// Create DIEs for each of the externally visible subprograms. // Create DIEs for each of the externally visible subprograms.
ConstructSubprogramDIEs(); ConstructSubprogramDIEs();
// Prime section data.
SectionMap.insert(std::string("\t") + TextSection);
} }
} }
@ -2412,6 +2425,12 @@ void DwarfWriter::EndModule() {
Asm->SwitchToDataSection(DataSection, 0); Asm->SwitchToDataSection(DataSection, 0);
EmitLabel("data_end", 0); EmitLabel("data_end", 0);
// End text sections.
for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Asm->SwitchToTextSection(SectionMap[i].c_str(), 0);
EmitLabel("section_end", i);
}
// Compute DIE offsets and sizes. // Compute DIE offsets and sizes.
SizeAndOffsets(); SizeAndOffsets();
@ -2445,24 +2464,17 @@ void DwarfWriter::EndModule() {
/// BeginFunction - Gather pre-function debug information. Assumes being /// BeginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point. /// emitted immediately after the function entry point.
void DwarfWriter::BeginFunction(MachineFunction *MF, bool IsNormalText) { void DwarfWriter::BeginFunction(MachineFunction *MF) {
this->MF = MF; this->MF = MF;
// FIXME - should be able to debug coalesced functions.
this->IsNormalText = IsNormalText;
// FIXME - should be able to debug coalesced functions. if (!ShouldEmitDwarf()) return;
if (IsNormalText) { EOL("Dwarf Begin Function");
// Begin accumulating function debug information.
DebugInfo->BeginFunction(MF); // Begin accumulating function debug information.
DebugInfo->BeginFunction(MF);
if (!ShouldEmitDwarf()) return;
EOL("Dwarf Begin Function");
// Assumes in correct section after the entry point. // Assumes in correct section after the entry point.
EmitLabel("func_begin", ++SubprogramCount); EmitLabel("func_begin", ++SubprogramCount);
} else {
ShouldEmitDwarf();
}
} }
/// EndFunction - Gather and emit post-function debug information. /// EndFunction - Gather and emit post-function debug information.
@ -2471,18 +2483,31 @@ void DwarfWriter::EndFunction() {
if (!ShouldEmitDwarf()) return; if (!ShouldEmitDwarf()) return;
EOL("Dwarf End Function"); EOL("Dwarf End Function");
// FIXME - should be able to debug coalesced functions. // Define end label for subprogram.
if (IsNormalText) { EmitLabel("func_end", SubprogramCount);
// Define end label for subprogram.
EmitLabel("func_end", SubprogramCount);
// Construct scopes for subprogram.
ConstructRootScope(DebugInfo->getRootScope());
// Emit function frame information. // Get function line info.
EmitFunctionDebugFrame(); std::vector<SourceLineInfo *> &LineInfos = DebugInfo->getSourceLines();
if (!LineInfos.empty()) {
// Get section line info.
unsigned ID = SectionMap.insert(Asm->CurrentSection);
if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
std::vector<SourceLineInfo *> &SectionLineInfos =SectionSourceLines[ID-1];
// Append the function info to section info.
SectionLineInfos.insert(SectionLineInfos.end(),
LineInfos.begin(), LineInfos.end());
} }
// Construct scopes for subprogram.
ConstructRootScope(DebugInfo->getRootScope());
// Emit function frame information.
EmitFunctionDebugFrame();
// Reset the line numbers for the next function.
LineInfos.clear();
// Clear function debug information. // Clear function debug information.
DebugInfo->EndFunction(); DebugInfo->EndFunction();
} }

View File

@ -489,8 +489,6 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
/// ///
bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>()); DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
// FIXME - should be able to debug coalesced functions.
bool IsNormalText = true;
SetupMachineFunction(MF); SetupMachineFunction(MF);
O << "\n\n"; O << "\n\n";
@ -518,14 +516,13 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.globl\t" << CurrentFnName << "\n";
O << "\t.weak_definition\t" << CurrentFnName << "\n"; O << "\t.weak_definition\t" << CurrentFnName << "\n";
IsNormalText = false;
break; break;
} }
EmitAlignment(4, F); EmitAlignment(4, F);
O << CurrentFnName << ":\n"; O << CurrentFnName << ":\n";
// Emit pre-function debug information. // Emit pre-function debug information.
DW.BeginFunction(&MF, IsNormalText); DW.BeginFunction(&MF);
// Print out code for the function. // Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();

View File

@ -29,8 +29,6 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Let PassManager know we need debug information and relay // Let PassManager know we need debug information and relay
// the MachineDebugInfo address on to DwarfWriter. // the MachineDebugInfo address on to DwarfWriter.
DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>()); DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
// FIXME - should be able to debug coalesced functions.
bool IsNormalText = true;
SetupMachineFunction(MF); SetupMachineFunction(MF);
O << "\n\n"; O << "\n\n";
@ -74,14 +72,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
SwitchToTextSection("", F); SwitchToTextSection("", F);
O << "\t.weak " << CurrentFnName << "\n"; O << "\t.weak " << CurrentFnName << "\n";
} }
IsNormalText = false;
break; break;
} }
O << CurrentFnName << ":\n"; O << CurrentFnName << ":\n";
if (Subtarget->TargetType == X86Subtarget::isDarwin) { if (Subtarget->TargetType == X86Subtarget::isDarwin) {
// Emit pre-function debug information. // Emit pre-function debug information.
DW.BeginFunction(&MF, IsNormalText); DW.BeginFunction(&MF);
} }
// Print out code for the function. // Print out code for the function.