[llvm] r211273 - Emit DWARF info for all code section in an assembly file

Eric Christopher echristo at gmail.com
Thu Jun 19 13:09:22 PDT 2014


FWIW since we're using DW_AT_string for debug_info the tests are too
strict since we can't rely on the offset within the section after a
string. I've relaxed this in r211308.

-eric

On Thu, Jun 19, 2014 at 8:52 AM, Oliver Stannard
<oliver.stannard at arm.com> wrote:
> Author: olista01
> Date: Thu Jun 19 10:52:37 2014
> New Revision: 211273
>
> URL: http://llvm.org/viewvc/llvm-project?rev=211273&view=rev
> Log:
> Emit DWARF info for all code section in an assembly file
>
> Currently, when using llvm as an assembler, DWARF debug information is only
> generated for the .text section. This patch modifies this so that DWARF info
> is emitted for all executable sections.
>
>
> Modified:
>     llvm/trunk/include/llvm/ADT/MapVector.h
>     llvm/trunk/include/llvm/MC/MCContext.h
>     llvm/trunk/include/llvm/MC/MCObjectStreamer.h
>     llvm/trunk/include/llvm/MC/MCStreamer.h
>     llvm/trunk/lib/MC/MCContext.cpp
>     llvm/trunk/lib/MC/MCDwarf.cpp
>     llvm/trunk/lib/MC/MCParser/AsmParser.cpp
>     llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp
>
> Modified: llvm/trunk/include/llvm/ADT/MapVector.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/MapVector.h?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/MapVector.h (original)
> +++ llvm/trunk/include/llvm/ADT/MapVector.h Thu Jun 19 10:52:37 2014
> @@ -123,6 +123,15 @@ public:
>      Map.erase(Pos);
>      Vector.pop_back();
>    }
> +
> +  /// \brief Remove the element given by Iterator.
> +  /// Returns an iterator to the element following the one which was removed,
> +  /// which may be end().
> +  typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
> +    typename MapType::iterator MapIterator = Map.find(Iterator->first);
> +    Map.erase(MapIterator);
> +    return Vector.erase(Iterator);
> +  }
>  };
>
>  }
>
> Modified: llvm/trunk/include/llvm/MC/MCContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCContext.h (original)
> +++ llvm/trunk/include/llvm/MC/MCContext.h Thu Jun 19 10:52:37 2014
> @@ -11,10 +11,12 @@
>  #define LLVM_MC_MCCONTEXT_H
>
>  #include "llvm/ADT/DenseMap.h"
> +#include "llvm/ADT/SetVector.h"
>  #include "llvm/ADT/SmallString.h"
>  #include "llvm/ADT/SmallVector.h"
>  #include "llvm/ADT/StringMap.h"
>  #include "llvm/MC/MCDwarf.h"
> +#include "llvm/MC/MCStreamer.h"
>  #include "llvm/MC/SectionKind.h"
>  #include "llvm/Support/Allocator.h"
>  #include "llvm/Support/Compiler.h"
> @@ -129,11 +131,10 @@ namespace llvm {
>      /// assembly source files.
>      unsigned GenDwarfFileNumber;
>
> -    /// The default initial text section that we generate dwarf debugging line
> -    /// info for when generating dwarf assembly source files.
> -    const MCSection *GenDwarfSection;
> -    /// Symbols created for the start and end of this section.
> -    MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
> +    /// Symbols created for the start and end of each section, used for
> +    /// generating the .debug_ranges and .debug_aranges sections.
> +    MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >
> +    SectionStartEndSyms;
>
>      /// The information gathered from labels that will have dwarf label
>      /// entries when generating dwarf assembly source files.
> @@ -374,16 +375,18 @@ namespace llvm {
>      void setGenDwarfFileNumber(unsigned FileNumber) {
>        GenDwarfFileNumber = FileNumber;
>      }
> -    const MCSection *getGenDwarfSection() { return GenDwarfSection; }
> -    void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
> -    MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
> -    void setGenDwarfSectionStartSym(MCSymbol *Sym) {
> -      GenDwarfSectionStartSym = Sym;
> -    }
> -    MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
> -    void setGenDwarfSectionEndSym(MCSymbol *Sym) {
> -      GenDwarfSectionEndSym = Sym;
> +    MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > &
> +    getGenDwarfSectionSyms() {
> +      return SectionStartEndSyms;
> +    }
> +    std::pair<MapVector<const MCSection *,
> +                        std::pair<MCSymbol *, MCSymbol *> >::iterator,
> +              bool>
> +    addGenDwarfSection(const MCSection *Sec) {
> +      return SectionStartEndSyms.insert(
> +          std::make_pair(Sec, std::make_pair(nullptr, nullptr)));
>      }
> +    void finalizeDwarfSections(MCStreamer &MCOS);
>      const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
>        return MCGenDwarfLabelEntries;
>      }
>
> Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Thu Jun 19 10:52:37 2014
> @@ -126,6 +126,10 @@ public:
>    void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
>    void EmitZeros(uint64_t NumBytes) override;
>    void FinishImpl() override;
> +
> +  virtual bool mayHaveInstructions() const {
> +    return getCurrentSectionData()->hasInstructions();
> +  }
>  };
>
>  } // end namespace llvm
>
> Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCStreamer.h Thu Jun 19 10:52:37 2014
> @@ -722,6 +722,8 @@ public:
>    virtual void FinishImpl() = 0;
>    /// Finish - Finish emission of machine code.
>    void Finish();
> +
> +  virtual bool mayHaveInstructions() const { return true; }
>  };
>
>  /// createNullStreamer - Create a dummy machine code streamer, which does
>
> Modified: llvm/trunk/lib/MC/MCContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCContext.cpp (original)
> +++ llvm/trunk/lib/MC/MCContext.cpp Thu Jun 19 10:52:37 2014
> @@ -340,6 +340,29 @@ bool MCContext::isValidDwarfFileNumber(u
>    return !MCDwarfFiles[FileNumber].Name.empty();
>  }
>
> +/// finalizeDwarfSections - Emit end symbols for each non-empty code section.
> +/// Also remove empty sections from SectionStartEndSyms, to avoid generating
> +/// useless debug info for them.
> +void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
> +  MCContext &context = MCOS.getContext();
> +
> +  auto sec = SectionStartEndSyms.begin();
> +  while (sec != SectionStartEndSyms.end()) {
> +    assert(sec->second.first && "Start symbol must be set by now");
> +    MCOS.SwitchSection(sec->first);
> +    if (MCOS.mayHaveInstructions()) {
> +      MCSymbol *SectionEndSym = context.CreateTempSymbol();
> +      MCOS.EmitLabel(SectionEndSym);
> +      sec->second.second = SectionEndSym;
> +      ++sec;
> +    } else {
> +      MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >::iterator
> +        to_erase = sec;
> +      sec = SectionStartEndSyms.erase(to_erase);
> +    }
> +  }
> +}
> +
>  void MCContext::FatalError(SMLoc Loc, const Twine &Msg) const {
>    // If we have a source manager and a location, use it. Otherwise just
>    // use the generic report_fatal_error().
>
> Modified: llvm/trunk/lib/MC/MCDwarf.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCDwarf.cpp (original)
> +++ llvm/trunk/lib/MC/MCDwarf.cpp Thu Jun 19 10:52:37 2014
> @@ -19,6 +19,7 @@
>  #include "llvm/MC/MCObjectFileInfo.h"
>  #include "llvm/MC/MCObjectStreamer.h"
>  #include "llvm/MC/MCRegisterInfo.h"
> +#include "llvm/MC/MCSection.h"
>  #include "llvm/MC/MCSymbol.h"
>  #include "llvm/Support/Debug.h"
>  #include "llvm/Support/ErrorHandling.h"
> @@ -518,8 +519,12 @@ static void EmitGenDwarfAbbrev(MCStreame
>    MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
>    MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
>    EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
> -  EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
> -  EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
> +  if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1) {
> +    EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
> +  } else {
> +    EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
> +    EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
> +  }
>    EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
>    if (!context.getCompilationDir().empty())
>      EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
> @@ -552,20 +557,14 @@ static void EmitGenDwarfAbbrev(MCStreame
>  }
>
>  // When generating dwarf for assembly source files this emits the data for
> -// .debug_aranges section.  Which contains a header and a table of pairs of
> -// PointerSize'ed values for the address and size of section(s) with line table
> -// entries (just the default .text in our case) and a terminating pair of zeros.
> +// .debug_aranges section. This section contains a header and a table of pairs
> +// of PointerSize'ed values for the address and size of section(s) with line
> +// table entries.
>  static void EmitGenDwarfAranges(MCStreamer *MCOS,
>                                  const MCSymbol *InfoSectionSymbol) {
>    MCContext &context = MCOS->getContext();
>
> -  // Create a symbol at the end of the section that we are creating the dwarf
> -  // debugging info to use later in here as part of the expression to calculate
> -  // the size of the section for the table.
> -  MCOS->SwitchSection(context.getGenDwarfSection());
> -  MCSymbol *SectionEndSym = context.CreateTempSymbol();
> -  MCOS->EmitLabel(SectionEndSym);
> -  context.setGenDwarfSectionEndSym(SectionEndSym);
> +  auto &Sections = context.getGenDwarfSectionSyms();
>
>    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
>
> @@ -583,8 +582,8 @@ static void EmitGenDwarfAranges(MCStream
>    Length += Pad;
>
>    // Add the size of the pair of PointerSize'ed values for the address and size
> -  // of the one default .text section we have in the table.
> -  Length += 2 * AddrSize;
> +  // of each section we have in the table.
> +  Length += 2 * AddrSize * Sections.size();
>    // And the pair of terminating zeros.
>    Length += 2 * AddrSize;
>
> @@ -608,14 +607,21 @@ static void EmitGenDwarfAranges(MCStream
>    for(int i = 0; i < Pad; i++)
>      MCOS->EmitIntValue(0, 1);
>
> -  // Now emit the table of pairs of PointerSize'ed values for the section(s)
> -  // address and size, in our case just the one default .text section.
> -  const MCExpr *Addr = MCSymbolRefExpr::Create(
> -    context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
> -  const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
> -    *context.getGenDwarfSectionStartSym(), *SectionEndSym, 0);
> -  MCOS->EmitValue(Addr, AddrSize);
> -  MCOS->EmitAbsValue(Size, AddrSize);
> +  // Now emit the table of pairs of PointerSize'ed values for the section
> +  // addresses and sizes.
> +  for (const auto &sec : Sections) {
> +    MCSymbol* StartSymbol = sec.second.first;
> +    MCSymbol* EndSymbol = sec.second.second;
> +    assert(StartSymbol && "StartSymbol must not be NULL");
> +    assert(EndSymbol && "EndSymbol must not be NULL");
> +
> +    const MCExpr *Addr = MCSymbolRefExpr::Create(
> +      StartSymbol, MCSymbolRefExpr::VK_None, context);
> +    const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
> +      *StartSymbol, *EndSymbol, 0);
> +    MCOS->EmitValue(Addr, AddrSize);
> +    MCOS->EmitAbsValue(Size, AddrSize);
> +  }
>
>    // And finally the pair of terminating zeros.
>    MCOS->EmitIntValue(0, AddrSize);
> @@ -627,7 +633,8 @@ static void EmitGenDwarfAranges(MCStream
>  // DIE and a list of label DIEs.
>  static void EmitGenDwarfInfo(MCStreamer *MCOS,
>                               const MCSymbol *AbbrevSectionSymbol,
> -                             const MCSymbol *LineSectionSymbol) {
> +                             const MCSymbol *LineSectionSymbol,
> +                             const MCSymbol *RangesSectionSymbol) {
>    MCContext &context = MCOS->getContext();
>
>    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
> @@ -674,15 +681,37 @@ static void EmitGenDwarfInfo(MCStreamer
>      MCOS->EmitIntValue(0, 4);
>    }
>
> -  // AT_low_pc, the first address of the default .text section.
> -  const MCExpr *Start = MCSymbolRefExpr::Create(
> -    context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
> -  MCOS->EmitValue(Start, AddrSize);
> -
> -  // AT_high_pc, the last address of the default .text section.
> -  const MCExpr *End = MCSymbolRefExpr::Create(
> -    context.getGenDwarfSectionEndSym(), MCSymbolRefExpr::VK_None, context);
> -  MCOS->EmitValue(End, AddrSize);
> +  if (RangesSectionSymbol) {
> +    // There are multiple sections containing code, so we must use the
> +    // .debug_ranges sections.
> +
> +    // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
> +    // to the address range list for this compilation unit.
> +    MCOS->EmitSymbolValue(RangesSectionSymbol, 4);
> +  } else {
> +    // If we only have one non-empty code section, we can use the simpler
> +    // AT_low_pc and AT_high_pc attributes.
> +
> +    // Find the first (and only) non-empty text section
> +    auto &Sections = context.getGenDwarfSectionSyms();
> +    const auto TextSection = Sections.begin();
> +    assert(TextSection != Sections.end() && "No text section found");
> +
> +    MCSymbol* StartSymbol = TextSection->second.first;
> +    MCSymbol* EndSymbol = TextSection->second.second;
> +    assert(StartSymbol && "StartSymbol must not be NULL");
> +    assert(EndSymbol && "EndSymbol must not be NULL");
> +
> +    // AT_low_pc, the first address of the default .text section.
> +    const MCExpr *Start = MCSymbolRefExpr::Create(
> +        StartSymbol, MCSymbolRefExpr::VK_None, context);
> +    MCOS->EmitValue(Start, AddrSize);
> +
> +    // AT_high_pc, the last address of the default .text section.
> +    const MCExpr *End = MCSymbolRefExpr::Create(
> +      EndSymbol, MCSymbolRefExpr::VK_None, context);
> +    MCOS->EmitValue(End, AddrSize);
> +  }
>
>    // AT_name, the name of the source file.  Reconstruct from the first directory
>    // and file table entries.
> @@ -766,13 +795,51 @@ static void EmitGenDwarfInfo(MCStreamer
>    MCOS->EmitLabel(InfoEnd);
>  }
>
> +// When generating dwarf for assembly source files this emits the data for
> +// .debug_ranges section. We only emit one range list, which spans all of the
> +// executable sections of this file.
> +static void EmitGenDwarfRanges(MCStreamer *MCOS) {
> +  MCContext &context = MCOS->getContext();
> +  auto &Sections = context.getGenDwarfSectionSyms();
> +
> +  const MCAsmInfo *AsmInfo = context.getAsmInfo();
> +  int AddrSize = AsmInfo->getPointerSize();
> +
> +  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
> +
> +  for (const auto sec : Sections) {
> +
> +    MCSymbol* StartSymbol = sec.second.first;
> +    MCSymbol* EndSymbol = sec.second.second;
> +    assert(StartSymbol && "StartSymbol must not be NULL");
> +    assert(EndSymbol && "EndSymbol must not be NULL");
> +
> +    // Emit a base address selection entry for the start of this section
> +    const MCExpr *SectionStartAddr = MCSymbolRefExpr::Create(
> +      StartSymbol, MCSymbolRefExpr::VK_None, context);
> +    MCOS->EmitFill(AddrSize, 0xFF);
> +    MCOS->EmitValue(SectionStartAddr, AddrSize);
> +
> +    // Emit a range list entry spanning this section
> +    const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
> +      *StartSymbol, *EndSymbol, 0);
> +    MCOS->EmitIntValue(0, AddrSize);
> +    MCOS->EmitAbsValue(SectionSize, AddrSize);
> +  }
> +
> +  // Emit end of list entry
> +  MCOS->EmitIntValue(0, AddrSize);
> +  MCOS->EmitIntValue(0, AddrSize);
> +}
> +
>  //
>  // When generating dwarf for assembly source files this emits the Dwarf
>  // sections.
>  //
>  void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
> -  // Create the dwarf sections in this order (.debug_line already created).
>    MCContext &context = MCOS->getContext();
> +
> +  // Create the dwarf sections in this order (.debug_line already created).
>    const MCAsmInfo *AsmInfo = context.getAsmInfo();
>    bool CreateDwarfSectionSymbols =
>        AsmInfo->doesDwarfUseRelocationsAcrossSections();
> @@ -781,6 +848,22 @@ void MCGenDwarfInfo::Emit(MCStreamer *MC
>      LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
>    MCSymbol *AbbrevSectionSymbol = nullptr;
>    MCSymbol *InfoSectionSymbol = nullptr;
> +  MCSymbol *RangesSectionSymbol = NULL;
> +
> +  // Create end symbols for each section, and remove empty sections
> +  MCOS->getContext().finalizeDwarfSections(*MCOS);
> +
> +  // If there are no sections to generate debug info for, we don't need
> +  // to do anything
> +  if (MCOS->getContext().getGenDwarfSectionSyms().empty())
> +    return;
> +
> +  // We only need to use the .debug_ranges section if we have multiple
> +  // code sections.
> +  const bool UseRangesSection =
> +      MCOS->getContext().getGenDwarfSectionSyms().size() > 1;
> +  CreateDwarfSectionSymbols |= UseRangesSection;
> +
>    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
>    if (CreateDwarfSectionSymbols) {
>      InfoSectionSymbol = context.CreateTempSymbol();
> @@ -791,20 +874,30 @@ void MCGenDwarfInfo::Emit(MCStreamer *MC
>      AbbrevSectionSymbol = context.CreateTempSymbol();
>      MCOS->EmitLabel(AbbrevSectionSymbol);
>    }
> -  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
> +  if (UseRangesSection) {
> +    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
> +    if (CreateDwarfSectionSymbols) {
> +      RangesSectionSymbol = context.CreateTempSymbol();
> +      MCOS->EmitLabel(RangesSectionSymbol);
> +    }
> +  }
>
> -  // If there are no line table entries then do not emit any section contents.
> -  if (!context.hasMCLineSections())
> -    return;
> +  assert((RangesSectionSymbol != NULL) || !UseRangesSection);
> +
> +  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
>
>    // Output the data for .debug_aranges section.
>    EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
>
> +  if (UseRangesSection)
> +    EmitGenDwarfRanges(MCOS);
> +
>    // Output the data for .debug_abbrev section.
>    EmitGenDwarfAbbrev(MCOS);
>
>    // Output the data for .debug_info section.
> -  EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol);
> +  EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol,
> +                   RangesSectionSymbol);
>  }
>
>  //
> @@ -815,12 +908,13 @@ void MCGenDwarfInfo::Emit(MCStreamer *MC
>  //
>  void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
>                                       SourceMgr &SrcMgr, SMLoc &Loc) {
> -  // We won't create dwarf labels for temporary symbols or symbols not in
> -  // the default text.
> +  // We won't create dwarf labels for temporary symbols.
>    if (Symbol->isTemporary())
>      return;
>    MCContext &context = MCOS->getContext();
> -  if (context.getGenDwarfSection() != MCOS->getCurrentSection().first)
> +  // We won't create dwarf labels for symbols in sections that we are not
> +  // generating debug info for.
> +  if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSection().first))
>      return;
>
>    // The dwarf label's name does not have the symbol name's leading
>
> Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
> +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Jun 19 10:52:37 2014
> @@ -633,10 +633,12 @@ bool AsmParser::Run(bool NoInitialTextSe
>    // If we are generating dwarf for assembly source files save the initial text
>    // section and generate a .file directive.
>    if (getContext().getGenDwarfForAssembly()) {
> -    getContext().setGenDwarfSection(getStreamer().getCurrentSection().first);
>      MCSymbol *SectionStartSym = getContext().CreateTempSymbol();
>      getStreamer().EmitLabel(SectionStartSym);
> -    getContext().setGenDwarfSectionStartSym(SectionStartSym);
> +    auto InsertResult = getContext().addGenDwarfSection(
> +        getStreamer().getCurrentSection().first);
> +    assert(InsertResult.second && ".text section should not have debug info yet");
> +    InsertResult.first->second.first = SectionStartSym;
>      getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
>          0, StringRef(), getContext().getMainFileName()));
>    }
> @@ -1592,12 +1594,11 @@ bool AsmParser::parseStatement(ParseStat
>      printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
>    }
>
> -  // If we are generating dwarf for assembly source files and the current
> -  // section is the initial text section then generate a .loc directive for
> -  // the instruction.
> +  // If we are generating dwarf for the current section then generate a .loc
> +  // directive for the instruction.
>    if (!HadError && getContext().getGenDwarfForAssembly() &&
> -      getContext().getGenDwarfSection() ==
> -          getStreamer().getCurrentSection().first) {
> +      getContext().getGenDwarfSectionSyms().count(
> +        getStreamer().getCurrentSection().first)) {
>
>      unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
>
> @@ -2029,7 +2030,7 @@ bool AsmParser::parseMacroArguments(cons
>            break;
>
>        if (FAI >= NParameters) {
> -       assert(M && "expected macro to be defined");
> +    assert(M && "expected macro to be defined");
>          Error(IDLoc,
>                "parameter named '" + FA.Name + "' does not exist for macro '" +
>                M->Name + "'");
>
> Modified: llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=211273&r1=211272&r2=211273&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp (original)
> +++ llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp Thu Jun 19 10:52:37 2014
> @@ -150,7 +150,7 @@ public:
>
>  private:
>    bool ParseSectionName(StringRef &SectionName);
> -  bool ParseSectionArguments(bool IsPush);
> +  bool ParseSectionArguments(bool IsPush, SMLoc loc);
>    unsigned parseSunStyleSectionFlags();
>  };
>
> @@ -382,7 +382,7 @@ unsigned ELFAsmParser::parseSunStyleSect
>  bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
>    getStreamer().PushSection();
>
> -  if (ParseSectionArguments(/*IsPush=*/true)) {
> +  if (ParseSectionArguments(/*IsPush=*/true, loc)) {
>      getStreamer().PopSection();
>      return true;
>    }
> @@ -397,11 +397,11 @@ bool ELFAsmParser::ParseDirectivePopSect
>  }
>
>  // FIXME: This is a work in progress.
> -bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
> -  return ParseSectionArguments(/*IsPush=*/false);
> +bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
> +  return ParseSectionArguments(/*IsPush=*/false, loc);
>  }
>
> -bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
> +bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
>    StringRef SectionName;
>
>    if (ParseSectionName(SectionName))
> @@ -545,10 +545,24 @@ EndStmt:
>    }
>
>    SectionKind Kind = computeSectionKind(Flags, Size);
> -  getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
> -                                                         Flags, Kind, Size,
> -                                                         GroupName),
> -                              Subsection);
> +  const MCSection *ELFSection = getContext().getELFSection(
> +      SectionName, Type, Flags, Kind, Size, GroupName);
> +  getStreamer().SwitchSection(ELFSection, Subsection);
> +
> +  if (getContext().getGenDwarfForAssembly()) {
> +    auto &Sections = getContext().getGenDwarfSectionSyms();
> +    auto InsertResult = Sections.insert(
> +        std::make_pair(ELFSection, std::make_pair(nullptr, nullptr)));
> +    if (InsertResult.second) {
> +      if (getContext().getDwarfVersion() <= 2)
> +        Error(loc, "DWARF2 only supports one section per compilation unit");
> +
> +      MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol();
> +      getStreamer().EmitLabel(SectionStartSymbol);
> +      InsertResult.first->second.first = SectionStartSymbol;
> +    }
> +  }
> +
>    return false;
>  }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list