diff options
| author | Bill Wendling <isanbard@gmail.com> | 2009-05-20 23:19:06 +0000 | 
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2009-05-20 23:19:06 +0000 | 
| commit | 2b128d70c511bf04ecf7b99ca0827e2a5fc65a5a (patch) | |
| tree | d75d67b79392a14e94acc3175eac48c671410368 | |
| parent | 8d7533d3e5b0186306414eca53a4e920904eeb26 (diff) | |
| download | bcm5719-llvm-2b128d70c511bf04ecf7b99ca0827e2a5fc65a5a.tar.gz bcm5719-llvm-2b128d70c511bf04ecf7b99ca0827e2a5fc65a5a.zip | |
Revert r72192. It was causing a build failure.
llvm-svn: 72193
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1509 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 77 | 
2 files changed, 807 insertions, 779 deletions
| diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index ad7184dd68e..086a8a5f60e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -275,9 +275,9 @@ void DwarfDebug::AssignAbbrevNumber(DIEAbbrev &Abbrev) {    }  } -/// CreateDIEEntry - Creates a new DIEEntry to be a proxy for a debug -/// information entry. -DIEEntry *DwarfDebug::CreateDIEEntry(DIE *Entry) { +/// NewDIEEntry - Creates a new DIEEntry to be a proxy for a debug information +/// entry. +DIEEntry *DwarfDebug::NewDIEEntry(DIE *Entry) {    DIEEntry *Value;    if (Entry) { @@ -545,7 +545,7 @@ void DwarfDebug::AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {    }    // Set up proxy. -  Slot = CreateDIEEntry(); +  Slot = NewDIEEntry();    // Construct type.    DIE Buffer(dwarf::DW_TAG_base_type); @@ -925,9 +925,9 @@ CompileUnit &DwarfDebug::FindCompileUnit(DICompileUnit Unit) const {    return *I->second;  } -/// CreateDbgScopeVariable - Create a new scope variable. +/// NewDbgScopeVariable - Create a new scope variable.  /// -DIE *DwarfDebug::CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) { +DIE *DwarfDebug::NewDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {    // Get the descriptor.    const DIVariable &VD = DV->getVariable(); @@ -1012,7 +1012,7 @@ void DwarfDebug::ConstructDbgScope(DbgScope *ParentScope,    // Add variables to scope.    SmallVector<DbgVariable *, 8> &Variables = ParentScope->getVariables();    for (unsigned i = 0, N = Variables.size(); i < N; ++i) { -    DIE *VariableDie = CreateDbgScopeVariable(Variables[i], Unit); +    DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit);      if (VariableDie) ParentDie->AddChild(VariableDie);    } @@ -1092,8 +1092,7 @@ void DwarfDebug::ConstructDbgScope(DbgScope *ParentScope,  /// ConstructFunctionDbgScope - Construct the scope for the subprogram.  /// -void DwarfDebug::ConstructFunctionDbgScope(DbgScope *RootScope, -                                           bool AbstractScope) { +void DwarfDebug::ConstructFunctionDbgScope(DbgScope *RootScope) {    // Exit if there is no root scope.    if (!RootScope) return;    DIDescriptor Desc = RootScope->getDesc(); @@ -1112,19 +1111,43 @@ void DwarfDebug::ConstructFunctionDbgScope(DbgScope *RootScope,    DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV());    assert(SPDie && "Missing subprogram descriptor"); -  if (!AbstractScope) { -    // Add the function bounds. -    AddLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, -             DWLabel("func_begin", SubprogramCount)); -    AddLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, -             DWLabel("func_end", SubprogramCount)); -    MachineLocation Location(RI->getFrameRegister(*MF)); -    AddAddress(SPDie, dwarf::DW_AT_frame_base, Location); -  } +  // Add the function bounds. +  AddLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, +           DWLabel("func_begin", SubprogramCount)); +  AddLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, +           DWLabel("func_end", SubprogramCount)); +  MachineLocation Location(RI->getFrameRegister(*MF)); +  AddAddress(SPDie, dwarf::DW_AT_frame_base, Location);    ConstructDbgScope(RootScope, 0, 0, SPDie, Unit);  } +/// ConstructFunctionDbgScope - Construct the scope for the abstract debug +/// scope. +/// +void DwarfDebug::ConstructAbstractDbgScope(DbgScope *AbsScope) { +  // Exit if there is no root scope. +  if (!AbsScope) return; + +  DIDescriptor Desc = AbsScope->getDesc(); +  if (Desc.isNull()) +    return; + +  // Get the subprogram debug information entry. +  DISubprogram SPD(Desc.getGV()); + +  // Get the compile unit context. +  CompileUnit *Unit = MainCU; +  if (!Unit) +    Unit = &FindCompileUnit(SPD.getCompileUnit()); + +  // Get the subprogram die. +  DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); +  assert(SPDie && "Missing subprogram descriptor"); + +  ConstructDbgScope(AbsScope, 0, 0, SPDie, Unit); +} +  /// ConstructDefaultDbgScope - Construct a default scope for the subprogram.  ///  void DwarfDebug::ConstructDefaultDbgScope(MachineFunction *MF) { @@ -1173,6 +1196,726 @@ void DwarfDebug::ConstructDefaultDbgScope(MachineFunction *MF) {  #endif  } +/// EmitInitial - Emit initial Dwarf declarations.  This is necessary for cc +/// tools to recognize the object file contains Dwarf information. +void DwarfDebug::EmitInitial() { +  // Check to see if we already emitted intial headers. +  if (didInitial) return; +  didInitial = true; + +  // Dwarf sections base addresses. +  if (TAI->doesDwarfRequireFrameSection()) { +    Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); +    EmitLabel("section_debug_frame", 0); +  } + +  Asm->SwitchToDataSection(TAI->getDwarfInfoSection()); +  EmitLabel("section_info", 0); +  Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection()); +  EmitLabel("section_abbrev", 0); +  Asm->SwitchToDataSection(TAI->getDwarfARangesSection()); +  EmitLabel("section_aranges", 0); + +  if (TAI->doesSupportMacInfoSection()) { +    Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); +    EmitLabel("section_macinfo", 0); +  } + +  Asm->SwitchToDataSection(TAI->getDwarfLineSection()); +  EmitLabel("section_line", 0); +  Asm->SwitchToDataSection(TAI->getDwarfLocSection()); +  EmitLabel("section_loc", 0); +  Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection()); +  EmitLabel("section_pubnames", 0); +  Asm->SwitchToDataSection(TAI->getDwarfStrSection()); +  EmitLabel("section_str", 0); +  Asm->SwitchToDataSection(TAI->getDwarfRangesSection()); +  EmitLabel("section_ranges", 0); + +  Asm->SwitchToSection(TAI->getTextSection()); +  EmitLabel("text_begin", 0); +  Asm->SwitchToSection(TAI->getDataSection()); +  EmitLabel("data_begin", 0); +} + +/// EmitDIE - Recusively Emits a debug information entry. +/// +void DwarfDebug::EmitDIE(DIE *Die) { +  // Get the abbreviation for this DIE. +  unsigned AbbrevNumber = Die->getAbbrevNumber(); +  const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; + +  Asm->EOL(); + +  // Emit the code (index) for the abbreviation. +  Asm->EmitULEB128Bytes(AbbrevNumber); + +  if (Asm->isVerbose()) +    Asm->EOL(std::string("Abbrev [" + +                         utostr(AbbrevNumber) + +                         "] 0x" + utohexstr(Die->getOffset()) + +                         ":0x" + utohexstr(Die->getSize()) + " " + +                         dwarf::TagString(Abbrev->getTag()))); +  else +    Asm->EOL(); + +  SmallVector<DIEValue*, 32> &Values = Die->getValues(); +  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData(); + +  // Emit the DIE attribute values. +  for (unsigned i = 0, N = Values.size(); i < N; ++i) { +    unsigned Attr = AbbrevData[i].getAttribute(); +    unsigned Form = AbbrevData[i].getForm(); +    assert(Form && "Too many attributes for DIE (check abbreviation)"); + +    switch (Attr) { +    case dwarf::DW_AT_sibling: +      Asm->EmitInt32(Die->SiblingOffset()); +      break; +    case dwarf::DW_AT_abstract_origin: { +      DIEEntry *E = cast<DIEEntry>(Values[i]); +      DIE *Origin = E->getEntry(); +      unsigned Addr = +        CompileUnitOffsets[Die->getAbstractCompileUnit()] + +        Origin->getOffset(); + +      Asm->EmitInt32(Addr); +      break; +    } +    default: +      // Emit an attribute using the defined form. +      Values[i]->EmitValue(this, Form); +      break; +    } + +    Asm->EOL(dwarf::AttributeString(Attr)); +  } + +  // Emit the DIE children if any. +  if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) { +    const std::vector<DIE *> &Children = Die->getChildren(); + +    for (unsigned j = 0, M = Children.size(); j < M; ++j) +      EmitDIE(Children[j]); + +    Asm->EmitInt8(0); Asm->EOL("End Of Children Mark"); +  } +} + +/// SizeAndOffsetDie - Compute the size and offset of a DIE. +/// +unsigned DwarfDebug::SizeAndOffsetDie(DIE *Die, unsigned Offset, bool Last) { +  // Get the children. +  const std::vector<DIE *> &Children = Die->getChildren(); + +  // If not last sibling and has children then add sibling offset attribute. +  if (!Last && !Children.empty()) Die->AddSiblingOffset(); + +  // Record the abbreviation. +  AssignAbbrevNumber(Die->getAbbrev()); + +  // Get the abbreviation for this DIE. +  unsigned AbbrevNumber = Die->getAbbrevNumber(); +  const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; + +  // Set DIE offset +  Die->setOffset(Offset); + +  // Start the size with the size of abbreviation code. +  Offset += TargetAsmInfo::getULEB128Size(AbbrevNumber); + +  const SmallVector<DIEValue*, 32> &Values = Die->getValues(); +  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData(); + +  // Size the DIE attribute values. +  for (unsigned i = 0, N = Values.size(); i < N; ++i) +    // Size attribute value. +    Offset += Values[i]->SizeOf(TD, AbbrevData[i].getForm()); + +  // Size the DIE children if any. +  if (!Children.empty()) { +    assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes && +           "Children flag not set"); + +    for (unsigned j = 0, M = Children.size(); j < M; ++j) +      Offset = SizeAndOffsetDie(Children[j], Offset, (j + 1) == M); + +    // End of children marker. +    Offset += sizeof(int8_t); +  } + +  Die->setSize(Offset - Die->getOffset()); +  return Offset; +} + +/// SizeAndOffsets - Compute the size and offset of all the DIEs. +/// +void DwarfDebug::SizeAndOffsets() { +  // Compute size of compile unit header. +  static unsigned Offset = +    sizeof(int32_t) + // Length of Compilation Unit Info +    sizeof(int16_t) + // DWARF version number +    sizeof(int32_t) + // Offset Into Abbrev. Section +    sizeof(int8_t);   // Pointer Size (in bytes) + +  // Process base compile unit. +  if (MainCU) { +    SizeAndOffsetDie(MainCU->getDie(), Offset, true); +    CompileUnitOffsets[MainCU] = 0; +    return; +  } + +  // Process all compile units. +  unsigned PrevOffset = 0; + +  for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) { +    CompileUnit *Unit = CompileUnits[i]; +    CompileUnitOffsets[Unit] = PrevOffset; +    PrevOffset += SizeAndOffsetDie(Unit->getDie(), Offset, true) +      + sizeof(int32_t);  // FIXME - extra pad for gdb bug. +  } +} + +/// EmitDebugInfo / EmitDebugInfoPerCU - Emit the debug info section. +/// +void DwarfDebug::EmitDebugInfoPerCU(CompileUnit *Unit) { +  DIE *Die = Unit->getDie(); + +  // Emit the compile units header. +  EmitLabel("info_begin", Unit->getID()); + +  // Emit size of content not including length itself +  unsigned ContentSize = Die->getSize() + +    sizeof(int16_t) + // DWARF version number +    sizeof(int32_t) + // Offset Into Abbrev. Section +    sizeof(int8_t) +  // Pointer Size (in bytes) +    sizeof(int32_t);  // FIXME - extra pad for gdb bug. + +  Asm->EmitInt32(ContentSize);  Asm->EOL("Length of Compilation Unit Info"); +  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number"); +  EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false); +  Asm->EOL("Offset Into Abbrev. Section"); +  Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); + +  EmitDIE(Die); +  // FIXME - extra padding for gdb bug. +  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); +  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); +  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); +  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); +  EmitLabel("info_end", Unit->getID()); + +  Asm->EOL(); +} + +void DwarfDebug::EmitDebugInfo() { +  // Start debug info section. +  Asm->SwitchToDataSection(TAI->getDwarfInfoSection()); + +  if (MainCU) { +    EmitDebugInfoPerCU(MainCU); +    return; +  } + +  for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) +    EmitDebugInfoPerCU(CompileUnits[i]); +} + +/// EmitAbbreviations - Emit the abbreviation section. +/// +void DwarfDebug::EmitAbbreviations() const { +  // Check to see if it is worth the effort. +  if (!Abbreviations.empty()) { +    // Start the debug abbrev section. +    Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection()); + +    EmitLabel("abbrev_begin", 0); + +    // For each abbrevation. +    for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) { +      // Get abbreviation data +      const DIEAbbrev *Abbrev = Abbreviations[i]; + +      // Emit the abbrevations code (base 1 index.) +      Asm->EmitULEB128Bytes(Abbrev->getNumber()); +      Asm->EOL("Abbreviation Code"); + +      // Emit the abbreviations data. +      Abbrev->Emit(Asm); + +      Asm->EOL(); +    } + +    // Mark end of abbreviations. +    Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(3)"); + +    EmitLabel("abbrev_end", 0); +    Asm->EOL(); +  } +} + +/// EmitEndOfLineMatrix - Emit the last address of the section and the end of +/// the line matrix. +/// +void DwarfDebug::EmitEndOfLineMatrix(unsigned SectionEnd) { +  // Define last address of section. +  Asm->EmitInt8(0); Asm->EOL("Extended Op"); +  Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); +  Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); +  EmitReference("section_end", SectionEnd); Asm->EOL("Section end label"); + +  // Mark end of matrix. +  Asm->EmitInt8(0); Asm->EOL("DW_LNE_end_sequence"); +  Asm->EmitULEB128Bytes(1); Asm->EOL(); +  Asm->EmitInt8(1); Asm->EOL(); +} + +/// EmitDebugLines - Emit source line information. +/// +void DwarfDebug::EmitDebugLines() { +  // If the target is using .loc/.file, the assembler will be emitting the +  // .debug_line table automatically. +  if (TAI->hasDotLocAndDotFile()) +    return; + +  // Minimum line delta, thus ranging from -10..(255-10). +  const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1); +  // Maximum line delta, thus ranging from -10..(255-10). +  const int MaxLineDelta = 255 + MinLineDelta; + +  // Start the dwarf line section. +  Asm->SwitchToDataSection(TAI->getDwarfLineSection()); + +  // Construct the section header. +  EmitDifference("line_end", 0, "line_begin", 0, true); +  Asm->EOL("Length of Source Line Info"); +  EmitLabel("line_begin", 0); + +  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number"); + +  EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0, true); +  Asm->EOL("Prolog Length"); +  EmitLabel("line_prolog_begin", 0); + +  Asm->EmitInt8(1); Asm->EOL("Minimum Instruction Length"); + +  Asm->EmitInt8(1); Asm->EOL("Default is_stmt_start flag"); + +  Asm->EmitInt8(MinLineDelta); Asm->EOL("Line Base Value (Special Opcodes)"); + +  Asm->EmitInt8(MaxLineDelta); Asm->EOL("Line Range Value (Special Opcodes)"); + +  Asm->EmitInt8(-MinLineDelta); Asm->EOL("Special Opcode Base"); + +  // Line number standard opcode encodings argument count +  Asm->EmitInt8(0); Asm->EOL("DW_LNS_copy arg count"); +  Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_pc arg count"); +  Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_line arg count"); +  Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_file arg count"); +  Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_column arg count"); +  Asm->EmitInt8(0); Asm->EOL("DW_LNS_negate_stmt arg count"); +  Asm->EmitInt8(0); Asm->EOL("DW_LNS_set_basic_block arg count"); +  Asm->EmitInt8(0); Asm->EOL("DW_LNS_const_add_pc arg count"); +  Asm->EmitInt8(1); Asm->EOL("DW_LNS_fixed_advance_pc arg count"); + +  // Emit directories. +  for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) { +    Asm->EmitString(getSourceDirectoryName(DI)); +    Asm->EOL("Directory"); +  } + +  Asm->EmitInt8(0); Asm->EOL("End of directories"); + +  // Emit files. +  for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) { +    // Remember source id starts at 1. +    std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI); +    Asm->EmitString(getSourceFileName(Id.second)); +    Asm->EOL("Source"); +    Asm->EmitULEB128Bytes(Id.first); +    Asm->EOL("Directory #"); +    Asm->EmitULEB128Bytes(0); +    Asm->EOL("Mod date"); +    Asm->EmitULEB128Bytes(0); +    Asm->EOL("File size"); +  } + +  Asm->EmitInt8(0); Asm->EOL("End of files"); + +  EmitLabel("line_prolog_end", 0); + +  // A sequence for each text section. +  unsigned SecSrcLinesSize = SectionSourceLines.size(); + +  for (unsigned j = 0; j < SecSrcLinesSize; ++j) { +    // Isolate current sections line info. +    const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j]; + +    if (Asm->isVerbose()) { +      const Section* S = SectionMap[j + 1]; +      O << '\t' << TAI->getCommentString() << " Section" +        << S->getName() << '\n'; +    } else { +      Asm->EOL(); +    } + +    // 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) { +      const SrcLineInfo &LineInfo = LineInfos[i]; +      unsigned LabelID = MMI->MappedLabel(LineInfo.getLabelID()); +      if (!LabelID) continue; + +      if (!Asm->isVerbose()) +        Asm->EOL(); +      else { +        std::pair<unsigned, unsigned> SourceID = +          getSourceDirectoryAndFileIds(LineInfo.getSourceID()); +        O << '\t' << TAI->getCommentString() << ' ' +          << getSourceDirectoryName(SourceID.first) << ' ' +          << getSourceFileName(SourceID.second) +          <<" :" << utostr_32(LineInfo.getLine()) << '\n'; +      } + +      // Define the line address. +      Asm->EmitInt8(0); Asm->EOL("Extended Op"); +      Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); +      Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); +      EmitReference("label",  LabelID); Asm->EOL("Location label"); + +      // If change of source, then switch to the new source. +      if (Source != LineInfo.getSourceID()) { +        Source = LineInfo.getSourceID(); +        Asm->EmitInt8(dwarf::DW_LNS_set_file); Asm->EOL("DW_LNS_set_file"); +        Asm->EmitULEB128Bytes(Source); Asm->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. +          Asm->EmitInt8(Delta - MinLineDelta); Asm->EOL("Line Delta"); +        } else { +          // ... otherwise use long hand. +          Asm->EmitInt8(dwarf::DW_LNS_advance_line); +          Asm->EOL("DW_LNS_advance_line"); +          Asm->EmitSLEB128Bytes(Offset); Asm->EOL("Line Offset"); +          Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy"); +        } +      } else { +        // Copy the previous row (different address or source) +        Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy"); +      } +    } + +    EmitEndOfLineMatrix(j + 1); +  } + +  if (SecSrcLinesSize == 0) +    // Because we're emitting a debug_line section, we still need a line +    // table. The linker and friends expect it to exist. If there's nothing to +    // put into it, emit an empty table. +    EmitEndOfLineMatrix(1); + +  EmitLabel("line_end", 0); +  Asm->EOL(); +} + +/// EmitCommonDebugFrame - Emit common frame info into a debug frame section. +/// +void DwarfDebug::EmitCommonDebugFrame() { +  if (!TAI->doesDwarfRequireFrameSection()) +    return; + +  int stackGrowth = +    Asm->TM.getFrameInfo()->getStackGrowthDirection() == +      TargetFrameInfo::StackGrowsUp ? +    TD->getPointerSize() : -TD->getPointerSize(); + +  // Start the dwarf frame section. +  Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); + +  EmitLabel("debug_frame_common", 0); +  EmitDifference("debug_frame_common_end", 0, +                 "debug_frame_common_begin", 0, true); +  Asm->EOL("Length of Common Information Entry"); + +  EmitLabel("debug_frame_common_begin", 0); +  Asm->EmitInt32((int)dwarf::DW_CIE_ID); +  Asm->EOL("CIE Identifier Tag"); +  Asm->EmitInt8(dwarf::DW_CIE_VERSION); +  Asm->EOL("CIE Version"); +  Asm->EmitString(""); +  Asm->EOL("CIE Augmentation"); +  Asm->EmitULEB128Bytes(1); +  Asm->EOL("CIE Code Alignment Factor"); +  Asm->EmitSLEB128Bytes(stackGrowth); +  Asm->EOL("CIE Data Alignment Factor"); +  Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false)); +  Asm->EOL("CIE RA Column"); + +  std::vector<MachineMove> Moves; +  RI->getInitialFrameState(Moves); + +  EmitFrameMoves(NULL, 0, Moves, false); + +  Asm->EmitAlignment(2, 0, 0, false); +  EmitLabel("debug_frame_common_end", 0); + +  Asm->EOL(); +} + +/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame +/// section. +void +DwarfDebug::EmitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){ +  if (!TAI->doesDwarfRequireFrameSection()) +    return; + +  // Start the dwarf frame section. +  Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); + +  EmitDifference("debug_frame_end", DebugFrameInfo.Number, +                 "debug_frame_begin", DebugFrameInfo.Number, true); +  Asm->EOL("Length of Frame Information Entry"); + +  EmitLabel("debug_frame_begin", DebugFrameInfo.Number); + +  EmitSectionOffset("debug_frame_common", "section_debug_frame", +                    0, 0, true, false); +  Asm->EOL("FDE CIE offset"); + +  EmitReference("func_begin", DebugFrameInfo.Number); +  Asm->EOL("FDE initial location"); +  EmitDifference("func_end", DebugFrameInfo.Number, +                 "func_begin", DebugFrameInfo.Number); +  Asm->EOL("FDE address range"); + +  EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, +                 false); + +  Asm->EmitAlignment(2, 0, 0, false); +  EmitLabel("debug_frame_end", DebugFrameInfo.Number); + +  Asm->EOL(); +} + +void DwarfDebug::EmitDebugPubNamesPerCU(CompileUnit *Unit) { +  EmitDifference("pubnames_end", Unit->getID(), +                 "pubnames_begin", Unit->getID(), true); +  Asm->EOL("Length of Public Names Info"); + +  EmitLabel("pubnames_begin", Unit->getID()); + +  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); + +  EmitSectionOffset("info_begin", "section_info", +                    Unit->getID(), 0, true, false); +  Asm->EOL("Offset of Compilation Unit Info"); + +  EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(), +                 true); +  Asm->EOL("Compilation Unit Length"); + +  StringMap<DIE*> &Globals = Unit->getGlobals(); +  for (StringMap<DIE*>::const_iterator +         GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { +    const char *Name = GI->getKeyData(); +    DIE * Entity = GI->second; + +    Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset"); +    Asm->EmitString(Name, strlen(Name)); Asm->EOL("External Name"); +  } + +  Asm->EmitInt32(0); Asm->EOL("End Mark"); +  EmitLabel("pubnames_end", Unit->getID()); + +  Asm->EOL(); +} + +/// EmitDebugPubNames - Emit visible names into a debug pubnames section. +/// +void DwarfDebug::EmitDebugPubNames() { +  // Start the dwarf pubnames section. +  Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection()); + +  if (MainCU) { +    EmitDebugPubNamesPerCU(MainCU); +    return; +  } + +  for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) +    EmitDebugPubNamesPerCU(CompileUnits[i]); +} + +/// EmitDebugStr - Emit visible names into a debug str section. +/// +void DwarfDebug::EmitDebugStr() { +  // Check to see if it is worth the effort. +  if (!StringPool.empty()) { +    // Start the dwarf str section. +    Asm->SwitchToDataSection(TAI->getDwarfStrSection()); + +    // For each of strings in the string pool. +    for (unsigned StringID = 1, N = StringPool.size(); +         StringID <= N; ++StringID) { +      // Emit a label for reference from debug information entries. +      EmitLabel("string", StringID); + +      // Emit the string itself. +      const std::string &String = StringPool[StringID]; +      Asm->EmitString(String); Asm->EOL(); +    } + +    Asm->EOL(); +  } +} + +/// EmitDebugLoc - Emit visible names into a debug loc section. +/// +void DwarfDebug::EmitDebugLoc() { +  // Start the dwarf loc section. +  Asm->SwitchToDataSection(TAI->getDwarfLocSection()); +  Asm->EOL(); +} + +/// EmitDebugARanges - Emit visible names into a debug aranges section. +/// +void DwarfDebug::EmitDebugARanges() { +  // Start the dwarf aranges section. +  Asm->SwitchToDataSection(TAI->getDwarfARangesSection()); + +  // FIXME - Mock up +#if 0 +  CompileUnit *Unit = GetBaseCompileUnit(); + +  // Don't include size of length +  Asm->EmitInt32(0x1c); Asm->EOL("Length of Address Ranges Info"); + +  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); + +  EmitReference("info_begin", Unit->getID()); +  Asm->EOL("Offset of Compilation Unit Info"); + +  Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address"); + +  Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor"); + +  Asm->EmitInt16(0);  Asm->EOL("Pad (1)"); +  Asm->EmitInt16(0);  Asm->EOL("Pad (2)"); + +  // Range 1 +  EmitReference("text_begin", 0); Asm->EOL("Address"); +  EmitDifference("text_end", 0, "text_begin", 0, true); Asm->EOL("Length"); + +  Asm->EmitInt32(0); Asm->EOL("EOM (1)"); +  Asm->EmitInt32(0); Asm->EOL("EOM (2)"); +#endif + +  Asm->EOL(); +} + +/// EmitDebugRanges - Emit visible names into a debug ranges section. +/// +void DwarfDebug::EmitDebugRanges() { +  // Start the dwarf ranges section. +  Asm->SwitchToDataSection(TAI->getDwarfRangesSection()); +  Asm->EOL(); +} + +/// EmitDebugMacInfo - Emit visible names into a debug macinfo section. +/// +void DwarfDebug::EmitDebugMacInfo() { +  if (TAI->doesSupportMacInfoSection()) { +    // Start the dwarf macinfo section. +    Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); +    Asm->EOL(); +  } +} + +/// EmitDebugInlineInfo - Emit inline info using following format. +/// Section Header: +/// 1. length of section +/// 2. Dwarf version number +/// 3. address size. +/// +/// Entries (one "entry" for each function that was inlined): +/// +/// 1. offset into __debug_str section for MIPS linkage name, if exists; +///   otherwise offset into __debug_str for regular function name. +/// 2. offset into __debug_str section for regular function name. +/// 3. an unsigned LEB128 number indicating the number of distinct inlining +/// instances for the function. +/// +/// The rest of the entry consists of a {die_offset, low_pc} pair for each +/// inlined instance; the die_offset points to the inlined_subroutine die in the +/// __debug_info section, and the low_pc is the starting address for the +/// inlining instance. +void DwarfDebug::EmitDebugInlineInfo() { +  if (!TAI->doesDwarfUsesInlineInfoSection()) +    return; + +  if (!MainCU) +    return; + +  Asm->SwitchToDataSection(TAI->getDwarfDebugInlineSection()); +  Asm->EOL(); +  EmitDifference("debug_inlined_end", 1, +                 "debug_inlined_begin", 1, true); +  Asm->EOL("Length of Debug Inlined Information Entry"); + +  EmitLabel("debug_inlined_begin", 1); + +  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); +  Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); + +  for (DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator +         I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { +    GlobalVariable *GV = I->first; +    SmallVector<unsigned, 4> &Labels = I->second; +    DISubprogram SP(GV); +    std::string Name; +    std::string LName; + +    SP.getLinkageName(LName); +    SP.getName(Name); + +    Asm->EmitString(LName.empty() ? Name : LName); +    Asm->EOL("MIPS linkage name"); + +    Asm->EmitString(Name); Asm->EOL("Function name"); + +    Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count"); + +    for (SmallVector<unsigned, 4>::iterator LI = Labels.begin(), +           LE = Labels.end(); LI != LE; ++LI) { +      DIE *SP = MainCU->getDieMapSlotFor(GV); +      Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset"); + +      if (TD->getPointerSize() == sizeof(int32_t)) +        O << TAI->getData32bitsDirective(); +      else +        O << TAI->getData64bitsDirective(); + +      PrintLabelName("label", *LI); Asm->EOL("low_pc"); +    } +  } + +  EmitLabel("debug_inlined_end", 1); +  Asm->EOL(); +} +  /// GetOrCreateSourceID - Look up the source id with the given directory and  /// source file names. If none currently exists, create a new id and insert it  /// in the SourceIds map. This can update DirectoryNames and SourceFileNames @@ -1564,7 +2307,7 @@ void DwarfDebug::EndFunction(MachineFunction *MF) {    for (SmallVector<DbgScope *, 32>::iterator           I = AbstractInstanceRootList.begin(),           E = AbstractInstanceRootList.end(); I != E; ++I) -    ConstructFunctionDbgScope(*I, true); +    ConstructAbstractDbgScope(*I);    // Construct scopes for subprogram.    if (FunctionDbgScope) @@ -1753,7 +2496,7 @@ void DwarfDebug::RecordVariable(GlobalVariable *GV, unsigned FrameIndex,      DebugTimer->stopTimer();  } -/// RecordInlinedFnStart - Indicate the start of inlined subroutine. +//// RecordInlinedFnStart - Indicate the start of inlined subroutine.  unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU,                                            unsigned Line, unsigned Col) {    unsigned LabelID = MMI->NextLabelID(); @@ -1811,7 +2554,6 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU,    MMI->RecordUsedDbgLabel(LabelID);    LexicalScopeStack.back()->AddConcreteInst(ConcreteScope); -  LexicalScopeStack.push_back(ConcreteScope);    // Keep track of the concrete scope that's inlined into this function.    DenseMap<GlobalVariable *, SmallVector<DbgScope *, 8> >::iterator @@ -1863,7 +2605,6 @@ unsigned DwarfDebug::RecordInlinedFnEnd(DISubprogram &SP) {    unsigned ID = MMI->NextLabelID();    MMI->RecordUsedDbgLabel(ID);    Scope->setEndLabelID(ID); -  LexicalScopeStack.pop_back();    if (TimePassesIsEnabled)      DebugTimer->stopTimer(); @@ -1897,727 +2638,3 @@ void DwarfDebug::RecordVariableScope(DIVariable &DV,    if (TimePassesIsEnabled)      DebugTimer->stopTimer();  } - -//===----------------------------------------------------------------------===// -// Emit Methods -//===----------------------------------------------------------------------===// - -/// SizeAndOffsetDie - Compute the size and offset of a DIE. -/// -unsigned DwarfDebug::SizeAndOffsetDie(DIE *Die, unsigned Offset, bool Last) { -  // Get the children. -  const std::vector<DIE *> &Children = Die->getChildren(); - -  // If not last sibling and has children then add sibling offset attribute. -  if (!Last && !Children.empty()) Die->AddSiblingOffset(); - -  // Record the abbreviation. -  AssignAbbrevNumber(Die->getAbbrev()); - -  // Get the abbreviation for this DIE. -  unsigned AbbrevNumber = Die->getAbbrevNumber(); -  const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; - -  // Set DIE offset -  Die->setOffset(Offset); - -  // Start the size with the size of abbreviation code. -  Offset += TargetAsmInfo::getULEB128Size(AbbrevNumber); - -  const SmallVector<DIEValue*, 32> &Values = Die->getValues(); -  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData(); - -  // Size the DIE attribute values. -  for (unsigned i = 0, N = Values.size(); i < N; ++i) -    // Size attribute value. -    Offset += Values[i]->SizeOf(TD, AbbrevData[i].getForm()); - -  // Size the DIE children if any. -  if (!Children.empty()) { -    assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes && -           "Children flag not set"); - -    for (unsigned j = 0, M = Children.size(); j < M; ++j) -      Offset = SizeAndOffsetDie(Children[j], Offset, (j + 1) == M); - -    // End of children marker. -    Offset += sizeof(int8_t); -  } - -  Die->setSize(Offset - Die->getOffset()); -  return Offset; -} - -/// SizeAndOffsets - Compute the size and offset of all the DIEs. -/// -void DwarfDebug::SizeAndOffsets() { -  // Compute size of compile unit header. -  static unsigned Offset = -    sizeof(int32_t) + // Length of Compilation Unit Info -    sizeof(int16_t) + // DWARF version number -    sizeof(int32_t) + // Offset Into Abbrev. Section -    sizeof(int8_t);   // Pointer Size (in bytes) - -  // Process base compile unit. -  if (MainCU) { -    SizeAndOffsetDie(MainCU->getDie(), Offset, true); -    CompileUnitOffsets[MainCU] = 0; -    return; -  } - -  // Process all compile units. -  unsigned PrevOffset = 0; - -  for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) { -    CompileUnit *Unit = CompileUnits[i]; -    CompileUnitOffsets[Unit] = PrevOffset; -    PrevOffset += SizeAndOffsetDie(Unit->getDie(), Offset, true) -      + sizeof(int32_t);  // FIXME - extra pad for gdb bug. -  } -} - -/// EmitInitial - Emit initial Dwarf declarations.  This is necessary for cc -/// tools to recognize the object file contains Dwarf information. -void DwarfDebug::EmitInitial() { -  // Check to see if we already emitted intial headers. -  if (didInitial) return; -  didInitial = true; - -  // Dwarf sections base addresses. -  if (TAI->doesDwarfRequireFrameSection()) { -    Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); -    EmitLabel("section_debug_frame", 0); -  } - -  Asm->SwitchToDataSection(TAI->getDwarfInfoSection()); -  EmitLabel("section_info", 0); -  Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection()); -  EmitLabel("section_abbrev", 0); -  Asm->SwitchToDataSection(TAI->getDwarfARangesSection()); -  EmitLabel("section_aranges", 0); - -  if (TAI->doesSupportMacInfoSection()) { -    Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); -    EmitLabel("section_macinfo", 0); -  } - -  Asm->SwitchToDataSection(TAI->getDwarfLineSection()); -  EmitLabel("section_line", 0); -  Asm->SwitchToDataSection(TAI->getDwarfLocSection()); -  EmitLabel("section_loc", 0); -  Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection()); -  EmitLabel("section_pubnames", 0); -  Asm->SwitchToDataSection(TAI->getDwarfStrSection()); -  EmitLabel("section_str", 0); -  Asm->SwitchToDataSection(TAI->getDwarfRangesSection()); -  EmitLabel("section_ranges", 0); - -  Asm->SwitchToSection(TAI->getTextSection()); -  EmitLabel("text_begin", 0); -  Asm->SwitchToSection(TAI->getDataSection()); -  EmitLabel("data_begin", 0); -} - -/// EmitDIE - Recusively Emits a debug information entry. -/// -void DwarfDebug::EmitDIE(DIE *Die) { -  // Get the abbreviation for this DIE. -  unsigned AbbrevNumber = Die->getAbbrevNumber(); -  const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; - -  Asm->EOL(); - -  // Emit the code (index) for the abbreviation. -  Asm->EmitULEB128Bytes(AbbrevNumber); - -  if (Asm->isVerbose()) -    Asm->EOL(std::string("Abbrev [" + -                         utostr(AbbrevNumber) + -                         "] 0x" + utohexstr(Die->getOffset()) + -                         ":0x" + utohexstr(Die->getSize()) + " " + -                         dwarf::TagString(Abbrev->getTag()))); -  else -    Asm->EOL(); - -  SmallVector<DIEValue*, 32> &Values = Die->getValues(); -  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData(); - -  // Emit the DIE attribute values. -  for (unsigned i = 0, N = Values.size(); i < N; ++i) { -    unsigned Attr = AbbrevData[i].getAttribute(); -    unsigned Form = AbbrevData[i].getForm(); -    assert(Form && "Too many attributes for DIE (check abbreviation)"); - -    switch (Attr) { -    case dwarf::DW_AT_sibling: -      Asm->EmitInt32(Die->SiblingOffset()); -      break; -    case dwarf::DW_AT_abstract_origin: { -      DIEEntry *E = cast<DIEEntry>(Values[i]); -      DIE *Origin = E->getEntry(); -      unsigned Addr = -        CompileUnitOffsets[Die->getAbstractCompileUnit()] + -        Origin->getOffset(); - -      Asm->EmitInt32(Addr); -      break; -    } -    default: -      // Emit an attribute using the defined form. -      Values[i]->EmitValue(this, Form); -      break; -    } - -    Asm->EOL(dwarf::AttributeString(Attr)); -  } - -  // Emit the DIE children if any. -  if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) { -    const std::vector<DIE *> &Children = Die->getChildren(); - -    for (unsigned j = 0, M = Children.size(); j < M; ++j) -      EmitDIE(Children[j]); - -    Asm->EmitInt8(0); Asm->EOL("End Of Children Mark"); -  } -} - -/// EmitDebugInfo / EmitDebugInfoPerCU - Emit the debug info section. -/// -void DwarfDebug::EmitDebugInfoPerCU(CompileUnit *Unit) { -  DIE *Die = Unit->getDie(); - -  // Emit the compile units header. -  EmitLabel("info_begin", Unit->getID()); - -  // Emit size of content not including length itself -  unsigned ContentSize = Die->getSize() + -    sizeof(int16_t) + // DWARF version number -    sizeof(int32_t) + // Offset Into Abbrev. Section -    sizeof(int8_t) +  // Pointer Size (in bytes) -    sizeof(int32_t);  // FIXME - extra pad for gdb bug. - -  Asm->EmitInt32(ContentSize);  Asm->EOL("Length of Compilation Unit Info"); -  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number"); -  EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false); -  Asm->EOL("Offset Into Abbrev. Section"); -  Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); - -  EmitDIE(Die); -  // FIXME - extra padding for gdb bug. -  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); -  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); -  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); -  Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); -  EmitLabel("info_end", Unit->getID()); - -  Asm->EOL(); -} - -void DwarfDebug::EmitDebugInfo() { -  // Start debug info section. -  Asm->SwitchToDataSection(TAI->getDwarfInfoSection()); - -  if (MainCU) { -    EmitDebugInfoPerCU(MainCU); -    return; -  } - -  for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) -    EmitDebugInfoPerCU(CompileUnits[i]); -} - -/// EmitAbbreviations - Emit the abbreviation section. -/// -void DwarfDebug::EmitAbbreviations() const { -  // Check to see if it is worth the effort. -  if (!Abbreviations.empty()) { -    // Start the debug abbrev section. -    Asm->SwitchToDataSection(TAI->getDwarfAbbrevSection()); - -    EmitLabel("abbrev_begin", 0); - -    // For each abbrevation. -    for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) { -      // Get abbreviation data -      const DIEAbbrev *Abbrev = Abbreviations[i]; - -      // Emit the abbrevations code (base 1 index.) -      Asm->EmitULEB128Bytes(Abbrev->getNumber()); -      Asm->EOL("Abbreviation Code"); - -      // Emit the abbreviations data. -      Abbrev->Emit(Asm); - -      Asm->EOL(); -    } - -    // Mark end of abbreviations. -    Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(3)"); - -    EmitLabel("abbrev_end", 0); -    Asm->EOL(); -  } -} - -/// EmitEndOfLineMatrix - Emit the last address of the section and the end of -/// the line matrix. -/// -void DwarfDebug::EmitEndOfLineMatrix(unsigned SectionEnd) { -  // Define last address of section. -  Asm->EmitInt8(0); Asm->EOL("Extended Op"); -  Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); -  Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); -  EmitReference("section_end", SectionEnd); Asm->EOL("Section end label"); - -  // Mark end of matrix. -  Asm->EmitInt8(0); Asm->EOL("DW_LNE_end_sequence"); -  Asm->EmitULEB128Bytes(1); Asm->EOL(); -  Asm->EmitInt8(1); Asm->EOL(); -} - -/// EmitDebugLines - Emit source line information. -/// -void DwarfDebug::EmitDebugLines() { -  // If the target is using .loc/.file, the assembler will be emitting the -  // .debug_line table automatically. -  if (TAI->hasDotLocAndDotFile()) -    return; - -  // Minimum line delta, thus ranging from -10..(255-10). -  const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1); -  // Maximum line delta, thus ranging from -10..(255-10). -  const int MaxLineDelta = 255 + MinLineDelta; - -  // Start the dwarf line section. -  Asm->SwitchToDataSection(TAI->getDwarfLineSection()); - -  // Construct the section header. -  EmitDifference("line_end", 0, "line_begin", 0, true); -  Asm->EOL("Length of Source Line Info"); -  EmitLabel("line_begin", 0); - -  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number"); - -  EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0, true); -  Asm->EOL("Prolog Length"); -  EmitLabel("line_prolog_begin", 0); - -  Asm->EmitInt8(1); Asm->EOL("Minimum Instruction Length"); - -  Asm->EmitInt8(1); Asm->EOL("Default is_stmt_start flag"); - -  Asm->EmitInt8(MinLineDelta); Asm->EOL("Line Base Value (Special Opcodes)"); - -  Asm->EmitInt8(MaxLineDelta); Asm->EOL("Line Range Value (Special Opcodes)"); - -  Asm->EmitInt8(-MinLineDelta); Asm->EOL("Special Opcode Base"); - -  // Line number standard opcode encodings argument count -  Asm->EmitInt8(0); Asm->EOL("DW_LNS_copy arg count"); -  Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_pc arg count"); -  Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_line arg count"); -  Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_file arg count"); -  Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_column arg count"); -  Asm->EmitInt8(0); Asm->EOL("DW_LNS_negate_stmt arg count"); -  Asm->EmitInt8(0); Asm->EOL("DW_LNS_set_basic_block arg count"); -  Asm->EmitInt8(0); Asm->EOL("DW_LNS_const_add_pc arg count"); -  Asm->EmitInt8(1); Asm->EOL("DW_LNS_fixed_advance_pc arg count"); - -  // Emit directories. -  for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) { -    Asm->EmitString(getSourceDirectoryName(DI)); -    Asm->EOL("Directory"); -  } - -  Asm->EmitInt8(0); Asm->EOL("End of directories"); - -  // Emit files. -  for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) { -    // Remember source id starts at 1. -    std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI); -    Asm->EmitString(getSourceFileName(Id.second)); -    Asm->EOL("Source"); -    Asm->EmitULEB128Bytes(Id.first); -    Asm->EOL("Directory #"); -    Asm->EmitULEB128Bytes(0); -    Asm->EOL("Mod date"); -    Asm->EmitULEB128Bytes(0); -    Asm->EOL("File size"); -  } - -  Asm->EmitInt8(0); Asm->EOL("End of files"); - -  EmitLabel("line_prolog_end", 0); - -  // A sequence for each text section. -  unsigned SecSrcLinesSize = SectionSourceLines.size(); - -  for (unsigned j = 0; j < SecSrcLinesSize; ++j) { -    // Isolate current sections line info. -    const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j]; - -    if (Asm->isVerbose()) { -      const Section* S = SectionMap[j + 1]; -      O << '\t' << TAI->getCommentString() << " Section" -        << S->getName() << '\n'; -    } else { -      Asm->EOL(); -    } - -    // 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) { -      const SrcLineInfo &LineInfo = LineInfos[i]; -      unsigned LabelID = MMI->MappedLabel(LineInfo.getLabelID()); -      if (!LabelID) continue; - -      if (!Asm->isVerbose()) -        Asm->EOL(); -      else { -        std::pair<unsigned, unsigned> SourceID = -          getSourceDirectoryAndFileIds(LineInfo.getSourceID()); -        O << '\t' << TAI->getCommentString() << ' ' -          << getSourceDirectoryName(SourceID.first) << ' ' -          << getSourceFileName(SourceID.second) -          <<" :" << utostr_32(LineInfo.getLine()) << '\n'; -      } - -      // Define the line address. -      Asm->EmitInt8(0); Asm->EOL("Extended Op"); -      Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); -      Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); -      EmitReference("label",  LabelID); Asm->EOL("Location label"); - -      // If change of source, then switch to the new source. -      if (Source != LineInfo.getSourceID()) { -        Source = LineInfo.getSourceID(); -        Asm->EmitInt8(dwarf::DW_LNS_set_file); Asm->EOL("DW_LNS_set_file"); -        Asm->EmitULEB128Bytes(Source); Asm->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. -          Asm->EmitInt8(Delta - MinLineDelta); Asm->EOL("Line Delta"); -        } else { -          // ... otherwise use long hand. -          Asm->EmitInt8(dwarf::DW_LNS_advance_line); -          Asm->EOL("DW_LNS_advance_line"); -          Asm->EmitSLEB128Bytes(Offset); Asm->EOL("Line Offset"); -          Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy"); -        } -      } else { -        // Copy the previous row (different address or source) -        Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy"); -      } -    } - -    EmitEndOfLineMatrix(j + 1); -  } - -  if (SecSrcLinesSize == 0) -    // Because we're emitting a debug_line section, we still need a line -    // table. The linker and friends expect it to exist. If there's nothing to -    // put into it, emit an empty table. -    EmitEndOfLineMatrix(1); - -  EmitLabel("line_end", 0); -  Asm->EOL(); -} - -/// EmitCommonDebugFrame - Emit common frame info into a debug frame section. -/// -void DwarfDebug::EmitCommonDebugFrame() { -  if (!TAI->doesDwarfRequireFrameSection()) -    return; - -  int stackGrowth = -    Asm->TM.getFrameInfo()->getStackGrowthDirection() == -      TargetFrameInfo::StackGrowsUp ? -    TD->getPointerSize() : -TD->getPointerSize(); - -  // Start the dwarf frame section. -  Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); - -  EmitLabel("debug_frame_common", 0); -  EmitDifference("debug_frame_common_end", 0, -                 "debug_frame_common_begin", 0, true); -  Asm->EOL("Length of Common Information Entry"); - -  EmitLabel("debug_frame_common_begin", 0); -  Asm->EmitInt32((int)dwarf::DW_CIE_ID); -  Asm->EOL("CIE Identifier Tag"); -  Asm->EmitInt8(dwarf::DW_CIE_VERSION); -  Asm->EOL("CIE Version"); -  Asm->EmitString(""); -  Asm->EOL("CIE Augmentation"); -  Asm->EmitULEB128Bytes(1); -  Asm->EOL("CIE Code Alignment Factor"); -  Asm->EmitSLEB128Bytes(stackGrowth); -  Asm->EOL("CIE Data Alignment Factor"); -  Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false)); -  Asm->EOL("CIE RA Column"); - -  std::vector<MachineMove> Moves; -  RI->getInitialFrameState(Moves); - -  EmitFrameMoves(NULL, 0, Moves, false); - -  Asm->EmitAlignment(2, 0, 0, false); -  EmitLabel("debug_frame_common_end", 0); - -  Asm->EOL(); -} - -/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame -/// section. -void -DwarfDebug::EmitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){ -  if (!TAI->doesDwarfRequireFrameSection()) -    return; - -  // Start the dwarf frame section. -  Asm->SwitchToDataSection(TAI->getDwarfFrameSection()); - -  EmitDifference("debug_frame_end", DebugFrameInfo.Number, -                 "debug_frame_begin", DebugFrameInfo.Number, true); -  Asm->EOL("Length of Frame Information Entry"); - -  EmitLabel("debug_frame_begin", DebugFrameInfo.Number); - -  EmitSectionOffset("debug_frame_common", "section_debug_frame", -                    0, 0, true, false); -  Asm->EOL("FDE CIE offset"); - -  EmitReference("func_begin", DebugFrameInfo.Number); -  Asm->EOL("FDE initial location"); -  EmitDifference("func_end", DebugFrameInfo.Number, -                 "func_begin", DebugFrameInfo.Number); -  Asm->EOL("FDE address range"); - -  EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, -                 false); - -  Asm->EmitAlignment(2, 0, 0, false); -  EmitLabel("debug_frame_end", DebugFrameInfo.Number); - -  Asm->EOL(); -} - -void DwarfDebug::EmitDebugPubNamesPerCU(CompileUnit *Unit) { -  EmitDifference("pubnames_end", Unit->getID(), -                 "pubnames_begin", Unit->getID(), true); -  Asm->EOL("Length of Public Names Info"); - -  EmitLabel("pubnames_begin", Unit->getID()); - -  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); - -  EmitSectionOffset("info_begin", "section_info", -                    Unit->getID(), 0, true, false); -  Asm->EOL("Offset of Compilation Unit Info"); - -  EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(), -                 true); -  Asm->EOL("Compilation Unit Length"); - -  StringMap<DIE*> &Globals = Unit->getGlobals(); -  for (StringMap<DIE*>::const_iterator -         GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { -    const char *Name = GI->getKeyData(); -    DIE * Entity = GI->second; - -    Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset"); -    Asm->EmitString(Name, strlen(Name)); Asm->EOL("External Name"); -  } - -  Asm->EmitInt32(0); Asm->EOL("End Mark"); -  EmitLabel("pubnames_end", Unit->getID()); - -  Asm->EOL(); -} - -/// EmitDebugPubNames - Emit visible names into a debug pubnames section. -/// -void DwarfDebug::EmitDebugPubNames() { -  // Start the dwarf pubnames section. -  Asm->SwitchToDataSection(TAI->getDwarfPubNamesSection()); - -  if (MainCU) { -    EmitDebugPubNamesPerCU(MainCU); -    return; -  } - -  for (unsigned i = 0, e = CompileUnits.size(); i != e; ++i) -    EmitDebugPubNamesPerCU(CompileUnits[i]); -} - -/// EmitDebugStr - Emit visible names into a debug str section. -/// -void DwarfDebug::EmitDebugStr() { -  // Check to see if it is worth the effort. -  if (!StringPool.empty()) { -    // Start the dwarf str section. -    Asm->SwitchToDataSection(TAI->getDwarfStrSection()); - -    // For each of strings in the string pool. -    for (unsigned StringID = 1, N = StringPool.size(); -         StringID <= N; ++StringID) { -      // Emit a label for reference from debug information entries. -      EmitLabel("string", StringID); - -      // Emit the string itself. -      const std::string &String = StringPool[StringID]; -      Asm->EmitString(String); Asm->EOL(); -    } - -    Asm->EOL(); -  } -} - -/// EmitDebugLoc - Emit visible names into a debug loc section. -/// -void DwarfDebug::EmitDebugLoc() { -  // Start the dwarf loc section. -  Asm->SwitchToDataSection(TAI->getDwarfLocSection()); -  Asm->EOL(); -} - -/// EmitDebugARanges - Emit visible names into a debug aranges section. -/// -void DwarfDebug::EmitDebugARanges() { -  // Start the dwarf aranges section. -  Asm->SwitchToDataSection(TAI->getDwarfARangesSection()); - -  // FIXME - Mock up -#if 0 -  CompileUnit *Unit = GetBaseCompileUnit(); - -  // Don't include size of length -  Asm->EmitInt32(0x1c); Asm->EOL("Length of Address Ranges Info"); - -  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); - -  EmitReference("info_begin", Unit->getID()); -  Asm->EOL("Offset of Compilation Unit Info"); - -  Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address"); - -  Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor"); - -  Asm->EmitInt16(0);  Asm->EOL("Pad (1)"); -  Asm->EmitInt16(0);  Asm->EOL("Pad (2)"); - -  // Range 1 -  EmitReference("text_begin", 0); Asm->EOL("Address"); -  EmitDifference("text_end", 0, "text_begin", 0, true); Asm->EOL("Length"); - -  Asm->EmitInt32(0); Asm->EOL("EOM (1)"); -  Asm->EmitInt32(0); Asm->EOL("EOM (2)"); -#endif - -  Asm->EOL(); -} - -/// EmitDebugRanges - Emit visible names into a debug ranges section. -/// -void DwarfDebug::EmitDebugRanges() { -  // Start the dwarf ranges section. -  Asm->SwitchToDataSection(TAI->getDwarfRangesSection()); -  Asm->EOL(); -} - -/// EmitDebugMacInfo - Emit visible names into a debug macinfo section. -/// -void DwarfDebug::EmitDebugMacInfo() { -  if (TAI->doesSupportMacInfoSection()) { -    // Start the dwarf macinfo section. -    Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); -    Asm->EOL(); -  } -} - -/// EmitDebugInlineInfo - Emit inline info using following format. -/// Section Header: -/// 1. length of section -/// 2. Dwarf version number -/// 3. address size. -/// -/// Entries (one "entry" for each function that was inlined): -/// -/// 1. offset into __debug_str section for MIPS linkage name, if exists; -///   otherwise offset into __debug_str for regular function name. -/// 2. offset into __debug_str section for regular function name. -/// 3. an unsigned LEB128 number indicating the number of distinct inlining -/// instances for the function. -/// -/// The rest of the entry consists of a {die_offset, low_pc} pair for each -/// inlined instance; the die_offset points to the inlined_subroutine die in the -/// __debug_info section, and the low_pc is the starting address for the -/// inlining instance. -void DwarfDebug::EmitDebugInlineInfo() { -  if (!TAI->doesDwarfUsesInlineInfoSection()) -    return; - -  if (!MainCU) -    return; - -  Asm->SwitchToDataSection(TAI->getDwarfDebugInlineSection()); -  Asm->EOL(); -  EmitDifference("debug_inlined_end", 1, -                 "debug_inlined_begin", 1, true); -  Asm->EOL("Length of Debug Inlined Information Entry"); - -  EmitLabel("debug_inlined_begin", 1); - -  Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); -  Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); - -  for (DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator -         I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { -    GlobalVariable *GV = I->first; -    SmallVector<unsigned, 4> &Labels = I->second; -    DISubprogram SP(GV); -    std::string Name; -    std::string LName; - -    SP.getLinkageName(LName); -    SP.getName(Name); - -    Asm->EmitString(LName.empty() ? Name : LName); -    Asm->EOL("MIPS linkage name"); - -    Asm->EmitString(Name); Asm->EOL("Function name"); - -    Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count"); - -    for (SmallVector<unsigned, 4>::iterator LI = Labels.begin(), -           LE = Labels.end(); LI != LE; ++LI) { -      DIE *SP = MainCU->getDieMapSlotFor(GV); -      Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset"); - -      if (TD->getPointerSize() == sizeof(int32_t)) -        O << TAI->getData32bitsDirective(); -      else -        O << TAI->getData64bitsDirective(); - -      PrintLabelName("label", *LI); Asm->EOL("low_pc"); -    } -  } - -  EmitLabel("debug_inlined_end", 1); -  Asm->EOL(); -} diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index a2647f87f37..a997199bed0 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -230,9 +230,16 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    ///    void AssignAbbrevNumber(DIEAbbrev &Abbrev); -  /// CreateDIEEntry - Creates a new DIEEntry to be a proxy for a debug -  /// information entry. -  DIEEntry *CreateDIEEntry(DIE *Entry = NULL); +  /// NewString - Add a string to the constant pool and returns a label. +  /// +  DWLabel NewString(const std::string &String) { +    unsigned StringID = StringPool.insert(String); +    return DWLabel("string", StringID); +  } + +  /// NewDIEEntry - Creates a new DIEEntry to be a proxy for a debug information +  /// entry. +  DIEEntry *NewDIEEntry(DIE *Entry = NULL);    /// SetDIEEntry - Set a DIEEntry once the debug information entry is defined.    /// @@ -275,7 +282,7 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    /// AddDIEEntry - Add a DIE attribute data and value.    ///    void AddDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) { -    Die->AddValue(Attribute, Form, CreateDIEEntry(Entry)); +    Die->AddValue(Attribute, Form, NewDIEEntry(Entry));    }    /// AddBlock - Add block data. @@ -339,9 +346,9 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    ///    CompileUnit &FindCompileUnit(DICompileUnit Unit) const; -  /// CreateDbgScopeVariable - Create a new debug scope variable. +  /// NewDbgScopeVariable - Create a new scope variable.    /// -  DIE *CreateDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit); +  DIE *NewDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit);    /// getOrCreateScope - Returns the scope associated with the given descriptor.    /// @@ -355,38 +362,17 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    /// ConstructFunctionDbgScope - Construct the scope for the subprogram.    /// -  void ConstructFunctionDbgScope(DbgScope *RootScope, -                                 bool AbstractScope = false); +  void ConstructFunctionDbgScope(DbgScope *RootScope); + +  /// ConstructFunctionDbgScope - Construct the scope for the abstract debug +  /// scope. +  /// +  void ConstructAbstractDbgScope(DbgScope *AbsScope);    /// ConstructDefaultDbgScope - Construct a default scope for the subprogram.    ///    void ConstructDefaultDbgScope(MachineFunction *MF); -  /// GetOrCreateSourceID - Look up the source id with the given directory and -  /// source file names. If none currently exists, create a new id and insert it -  /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps -  /// as well. -  unsigned GetOrCreateSourceID(const std::string &DirName, -                               const std::string &FileName); - -  void ConstructCompileUnit(GlobalVariable *GV); - -  /// ConstructCompileUnits - Create a compile unit DIEs. -  void ConstructCompileUnits(); - -  bool ConstructGlobalVariableDIE(GlobalVariable *GV); - -  /// ConstructGlobalVariableDIEs - Create DIEs for each of the externally  -  /// visible global variables. Return true if at least one global DIE is -  /// created. -  bool ConstructGlobalVariableDIEs(); - -  bool ConstructSubprogram(GlobalVariable *GV); - -  /// ConstructSubprograms - Create DIEs for each of the externally visible -  /// subprograms. Return true if at least one subprogram DIE is created. -  bool ConstructSubprograms(); -    /// EmitInitial - Emit initial Dwarf declarations.  This is necessary for cc    /// tools to recognize the object file contains Dwarf information.    void EmitInitial(); @@ -475,6 +461,31 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    /// the __debug_info section, and the low_pc is the starting address  for the    ///  inlining instance.    void EmitDebugInlineInfo(); + +  /// GetOrCreateSourceID - Look up the source id with the given directory and +  /// source file names. If none currently exists, create a new id and insert it +  /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps +  /// as well. +  unsigned GetOrCreateSourceID(const std::string &DirName, +                               const std::string &FileName); + +  void ConstructCompileUnit(GlobalVariable *GV); + +  /// ConstructCompileUnits - Create a compile unit DIEs. +  void ConstructCompileUnits(); + +  bool ConstructGlobalVariableDIE(GlobalVariable *GV); + +  /// ConstructGlobalVariableDIEs - Create DIEs for each of the externally  +  /// visible global variables. Return true if at least one global DIE is +  /// created. +  bool ConstructGlobalVariableDIEs(); + +  bool ConstructSubprogram(GlobalVariable *GV); + +  /// ConstructSubprograms - Create DIEs for each of the externally visible +  /// subprograms. Return true if at least one subprogram DIE is created. +  bool ConstructSubprograms();  public:    //===--------------------------------------------------------------------===//    // Main entry points. | 

