Commit dcf6494a authored by Alexey Lapshin's avatar Alexey Lapshin
Browse files

LLD already has a mechanism for caching creation of DWARCContext:

llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });

Though it is not used in all places.

I need that patch for implementing "Remove obsolete debug info" feature
(D74169). But this caching mechanism is useful by itself, and I think it
would be good to use it without connection to "Remove obsolete debug info"
feature. So this patch changes inplace creation of DWARFContext with
its cached version.

Depends on D74308

Reviewed By: ruiu

Differential Revision: https://reviews.llvm.org/D74773
parent 000847f8
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -264,9 +264,17 @@ std::string InputFile::getSrcMsg(const Symbol &sym, InputSectionBase &sec,
  }
}

template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
  dwarf = make<DWARFCache>(std::make_unique<DWARFContext>(
      std::make_unique<LLDDwarfObj<ELFT>>(this)));
template <class ELFT> DWARFCache *ObjFile<ELFT>::getDwarf() {
  llvm::call_once(initDwarf, [this]() {
    dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>(
        std::make_unique<LLDDwarfObj<ELFT>>(this), "",
        [&](Error err) { warn(getName() + ": " + toString(std::move(err))); },
        [&](Error warning) {
          warn(getName() + ": " + toString(std::move(warning)));
        }));
  });

  return dwarf.get();
}

// Returns the pair of file name and line number describing location of data
@@ -274,9 +282,7 @@ template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
template <class ELFT>
Optional<std::pair<std::string, unsigned>>
ObjFile<ELFT>::getVariableLoc(StringRef name) {
  llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });

  return dwarf->getVariableLoc(name);
  return getDwarf()->getVariableLoc(name);
}

// Returns source line information for a given offset
@@ -284,8 +290,6 @@ ObjFile<ELFT>::getVariableLoc(StringRef name) {
template <class ELFT>
Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
                                                  uint64_t offset) {
  llvm::call_once(initDwarfLine, [this]() { initializeDwarf(); });

  // Detect SectionIndex for specified section.
  uint64_t sectionIndex = object::SectionedAddress::UndefSection;
  ArrayRef<InputSectionBase *> sections = s->file->getSections();
@@ -296,7 +300,7 @@ Optional<DILineInfo> ObjFile<ELFT>::getDILineInfo(InputSectionBase *s,
    }
  }

  return dwarf->getDILineInfo(offset, sectionIndex);
  return getDwarf()->getDILineInfo(offset, sectionIndex);
}

ELFFileBase::ELFFileBase(Kind k, MemoryBufferRef mb) : InputFile(k, mb) {
+6 −3
Original line number Diff line number Diff line
@@ -250,11 +250,14 @@ public:
  // SHT_LLVM_CALL_GRAPH_PROFILE table
  ArrayRef<Elf_CGProfile> cgProfile;

  // Get cached DWARF information.
  DWARFCache *getDwarf();

private:
  void initializeSections(bool ignoreComdats);
  void initializeSymbols();
  void initializeJustSymbols();
  void initializeDwarf();

  InputSectionBase *getRelocTarget(const Elf_Shdr &sec);
  InputSectionBase *createInputSection(const Elf_Shdr &sec);
  StringRef getSectionName(const Elf_Shdr &sec);
@@ -282,8 +285,8 @@ private:
  // reporting. Linker may find reasonable number of errors in a
  // single object file, so we cache debugging information in order to
  // parse it only once for each object file we link.
  DWARFCache *dwarf;
  llvm::once_flag initDwarfLine;
  std::unique_ptr<DWARFCache> dwarf;
  llvm::once_flag initDwarf;
};

// LazyObjFile is analogous to ArchiveFile in the sense that
+6 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "Symbols.h"
#include "Target.h"
#include "Writer.h"
#include "lld/Common/DWARF.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
@@ -2821,14 +2822,14 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
  std::vector<std::vector<NameAttrEntry>> nameAttrs(sections.size());

  parallelForEachN(0, sections.size(), [&](size_t i) {
    ObjFile<ELFT> *file = sections[i]->getFile<ELFT>();
    DWARFContext dwarf(std::make_unique<LLDDwarfObj<ELFT>>(file));
    DWARFContext *dwarf =
        sections[i]->getFile<ELFT>()->getDwarf()->getContext();

    chunks[i].sec = sections[i];
    chunks[i].compilationUnits = readCuList(dwarf);
    chunks[i].addressAreas = readAddressAreas(dwarf, sections[i]);
    chunks[i].compilationUnits = readCuList(*dwarf);
    chunks[i].addressAreas = readAddressAreas(*dwarf, sections[i]);
    nameAttrs[i] = readPubNamesAndTypes<ELFT>(
        static_cast<const LLDDwarfObj<ELFT> &>(dwarf.getDWARFObj()),
        static_cast<const LLDDwarfObj<ELFT> &>(dwarf->getDWARFObj()),
        chunks[i].compilationUnits);
  });

+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ public:
  llvm::Optional<std::pair<std::string, unsigned>>
  getVariableLoc(StringRef name);

  llvm::DWARFContext *getContext() { return dwarf.get(); }

private:
  std::unique_ptr<llvm::DWARFContext> dwarf;
  std::vector<const llvm::DWARFDebugLine::LineTable *> lineTables;
+2 −2
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@
# RUN: llvm-ar rc %t.a %t.o
# RUN: ld.lld --gdb-index -e main %t2.o %t.a -o /dev/null 2>&1 | FileCheck --check-prefix=ARCHIVE %s

# CHECK: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.o:(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
# ARCHIVE: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):(.debug_info): decoding address ranges: invalid range list entry at offset 0x10
# CHECK: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.o:{{(\(\.debug_info\):)?}} decoding address ranges: invalid range list entry at offset 0x10
# ARCHIVE: ld.lld: warning: {{.*}}gdb-index-invalid-ranges.s.tmp.a(gdb-index-invalid-ranges.s.tmp.o):{{(\(\.debug_info\):)?}} decoding address ranges: invalid range list entry at offset 0x10

.section .text.foo1,"ax",@progbits
.globl f1
Loading