[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