[lld] 666de79 - [ELF] Move some ObjFile members to ELFFileBase to simplify getSrcMsg

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 29 15:48:52 PST 2024


Author: Fangrui Song
Date: 2024-11-29T15:48:46-08:00
New Revision: 666de79595dc2460b7abca0b99d79d058c10cadf

URL: https://github.com/llvm/llvm-project/commit/666de79595dc2460b7abca0b99d79d058c10cadf
DIFF: https://github.com/llvm/llvm-project/commit/666de79595dc2460b7abca0b99d79d058c10cadf.diff

LOG: [ELF] Move some ObjFile members to ELFFileBase to simplify getSrcMsg

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp
    lld/ELF/InputFiles.h
    lld/ELF/InputSection.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 83a25e1b66cff0..3af9bc02a255a6 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -375,39 +375,29 @@ static std::string createFileLineMsg(StringRef path, unsigned line) {
   return filename + lineno + " (" + path.str() + lineno + ")";
 }
 
-template <class ELFT>
-static std::string getSrcMsgAux(ObjFile<ELFT> &file, const Symbol &sym,
-                                const InputSectionBase &sec, uint64_t offset) {
-  // In DWARF, functions and variables are stored to 
diff erent places.
-  // First, look up a function for a given offset.
-  if (std::optional<DILineInfo> info = file.getDILineInfo(&sec, offset))
+std::string InputFile::getSrcMsg(const InputSectionBase &sec, const Symbol &sym,
+                                 uint64_t offset) {
+  if (kind() != ObjKind)
+    return "";
+
+  // First, look up the DWARF line table.
+  ArrayRef<InputSectionBase *> sections = getSections();
+  auto it = llvm::find(sections, &sec);
+  uint64_t sectionIndex = it != sections.end()
+                              ? it - sections.begin()
+                              : object::SectionedAddress::UndefSection;
+  DWARFCache *dwarf = cast<ELFFileBase>(this)->getDwarf();
+  if (std::optional<DILineInfo> info =
+          dwarf->getDILineInfo(offset, sectionIndex))
     return createFileLineMsg(info->FileName, info->Line);
 
   // If it failed, look up again as a variable.
   if (std::optional<std::pair<std::string, unsigned>> fileLine =
-          file.getVariableLoc(sym.getName()))
+          dwarf->getVariableLoc(sym.getName()))
     return createFileLineMsg(fileLine->first, fileLine->second);
 
   // File.sourceFile contains STT_FILE symbol, and that is a last resort.
-  return std::string(file.sourceFile);
-}
-
-std::string InputFile::getSrcMsg(const Symbol &sym, const InputSectionBase &sec,
-                                 uint64_t offset) {
-  if (kind() != ObjKind)
-    return "";
-  switch (ekind) {
-  default:
-    llvm_unreachable("Invalid kind");
-  case ELF32LEKind:
-    return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), sym, sec, offset);
-  case ELF32BEKind:
-    return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), sym, sec, offset);
-  case ELF64LEKind:
-    return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), sym, sec, offset);
-  case ELF64BEKind:
-    return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset);
-  }
+  return std::string(cast<ELFFileBase>(this)->sourceFile);
 }
 
 StringRef InputFile::getNameForScript() const {
@@ -480,43 +470,32 @@ static void handleSectionGroup(ArrayRef<InputSectionBase *> sections,
     prev->nextInSectionGroup = head;
 }
 
-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(ctx) << getName() + ": " << std::move(err); },
-        [&](Error warning) {
-          Warn(ctx) << getName() << ": " << std::move(warning);
-        }));
-  });
-
-  return dwarf.get();
+template <class ELFT> void ObjFile<ELFT>::initDwarf() {
+  dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>(
+      std::make_unique<LLDDwarfObj<ELFT>>(this), "",
+      [&](Error err) { Warn(ctx) << getName() + ": " << std::move(err); },
+      [&](Error warning) {
+        Warn(ctx) << getName() << ": " << std::move(warning);
+      }));
 }
 
-// Returns the pair of file name and line number describing location of data
-// object (variable, array, etc) definition.
-template <class ELFT>
-std::optional<std::pair<std::string, unsigned>>
-ObjFile<ELFT>::getVariableLoc(StringRef name) {
-  return getDwarf()->getVariableLoc(name);
-}
-
-// Returns source line information for a given offset
-// using DWARF debug info.
-template <class ELFT>
-std::optional<DILineInfo>
-ObjFile<ELFT>::getDILineInfo(const InputSectionBase *s, uint64_t offset) {
-  // Detect SectionIndex for specified section.
-  uint64_t sectionIndex = object::SectionedAddress::UndefSection;
-  ArrayRef<InputSectionBase *> sections = s->file->getSections();
-  for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) {
-    if (s == sections[curIndex]) {
-      sectionIndex = curIndex;
-      break;
+DWARFCache *ELFFileBase::getDwarf() {
+  assert(fileKind == ObjKind);
+  llvm::call_once(initDwarf, [this]() {
+    switch (ekind) {
+    default:
+      llvm_unreachable("");
+    case ELF32LEKind:
+      return cast<ObjFile<ELF32LE>>(this)->initDwarf();
+    case ELF32BEKind:
+      return cast<ObjFile<ELF32BE>>(this)->initDwarf();
+    case ELF64LEKind:
+      return cast<ObjFile<ELF64LE>>(this)->initDwarf();
+    case ELF64BEKind:
+      return cast<ObjFile<ELF64BE>>(this)->initDwarf();
     }
-  }
-
-  return getDwarf()->getDILineInfo(offset, sectionIndex);
+  });
+  return dwarf.get();
 }
 
 ELFFileBase::ELFFileBase(Ctx &ctx, Kind k, ELFKind ekind, MemoryBufferRef mb)
@@ -524,6 +503,8 @@ ELFFileBase::ELFFileBase(Ctx &ctx, Kind k, ELFKind ekind, MemoryBufferRef mb)
   this->ekind = ekind;
 }
 
+ELFFileBase::~ELFFileBase() {}
+
 template <typename Elf_Shdr>
 static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> sections, uint32_t type) {
   for (const Elf_Shdr &sec : sections)

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 9161fa13ad983c..b567cda6831293 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -147,7 +147,7 @@ class InputFile {
   // True if this is an argument for --just-symbols. Usually false.
   bool justSymbols = false;
 
-  std::string getSrcMsg(const Symbol &sym, const InputSectionBase &sec,
+  std::string getSrcMsg(const InputSectionBase &sec, const Symbol &sym,
                         uint64_t offset);
 
   // On PPC64 we need to keep track of which files contain small code model
@@ -181,6 +181,7 @@ class InputFile {
 class ELFFileBase : public InputFile {
 public:
   ELFFileBase(Ctx &ctx, Kind k, ELFKind ekind, MemoryBufferRef m);
+  ~ELFFileBase();
   static bool classof(const InputFile *f) { return f->isElf(); }
 
   void init();
@@ -216,6 +217,9 @@ class ELFFileBase : public InputFile {
     return getELFSyms<ELFT>().slice(firstGlobal);
   }
 
+  // Get cached DWARF information.
+  DWARFCache *getDwarf();
+
 protected:
   // Initializes this class's member variables.
   template <typename ELFT> void init(InputFile::Kind k);
@@ -227,7 +231,18 @@ class ELFFileBase : public InputFile {
   uint32_t numELFSyms = 0;
   uint32_t firstGlobal = 0;
 
+  // Below are ObjFile specific members.
+
+  // Debugging information to retrieve source file and line for error
+  // 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.
+  llvm::once_flag initDwarf;
+  std::unique_ptr<DWARFCache> dwarf;
+
 public:
+  // Name of source file obtained from STT_FILE, if present.
+  StringRef sourceFile;
   uint32_t andFeatures = 0;
   bool hasCommonSyms = false;
   ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
@@ -257,15 +272,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
 
   uint32_t getSectionIndex(const Elf_Sym &sym) const;
 
-  std::optional<llvm::DILineInfo> getDILineInfo(const InputSectionBase *,
-                                                uint64_t);
-  std::optional<std::pair<std::string, unsigned>>
-  getVariableLoc(StringRef name);
-
-  // Name of source file obtained from STT_FILE symbol value,
-  // or empty string if there is no such symbol in object file
-  // symbol table.
-  StringRef sourceFile;
 
   // Pointer to this input file's .llvm_addrsig section, if it has one.
   const Elf_Shdr *addrsigSec = nullptr;
@@ -286,8 +292,7 @@ template <class ELFT> class ObjFile : public ELFFileBase {
   // but had one or more functions with the no_split_stack attribute.
   bool someNoSplitStack = false;
 
-  // Get cached DWARF information.
-  DWARFCache *getDwarf();
+  void initDwarf();
 
   void initSectionsAndLocalSyms(bool ignoreComdats);
   void postParse();
@@ -318,13 +323,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
   // The following variable contains the contents of .symtab_shndx.
   // If the section does not exist (which is common), the array is empty.
   ArrayRef<Elf_Word> shndxTable;
-
-  // Debugging information to retrieve source file and line for error
-  // 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.
-  std::unique_ptr<DWARFCache> dwarf;
-  llvm::once_flag initDwarf;
 };
 
 class BitcodeFile : public InputFile {

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index dc2a0edd9bf248..48facf3312b0c5 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -324,7 +324,7 @@ std::string InputSectionBase::getLocation(uint64_t offset) const {
 //  Returns an empty string if there's no way to get line info.
 std::string InputSectionBase::getSrcMsg(const Symbol &sym,
                                         uint64_t offset) const {
-  return file->getSrcMsg(sym, *this, offset);
+  return file->getSrcMsg(*this, sym, offset);
 }
 
 // Returns a filename string along with an optional section name. This


        


More information about the llvm-commits mailing list