diff options
| author | Fangrui Song <i@maskray.me> | 2024-11-29 15:48:46 -0800 |
|---|---|---|
| committer | Fangrui Song <i@maskray.me> | 2024-11-29 15:48:46 -0800 |
| commit | 666de79595dc2460b7abca0b99d79d058c10cadf (patch) | |
| tree | 8adebdf5694fd0a4df4862e3c5b83f9d2a3ea27d /lld/ELF/InputFiles.cpp | |
| parent | 8ac2b77a11c9db9879557ce1c26e38628e1ef45f (diff) | |
[ELF] Move some ObjFile members to ELFFileBase to simplify getSrcMsg
Diffstat (limited to 'lld/ELF/InputFiles.cpp')
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 101 |
1 files changed, 41 insertions, 60 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 83a25e1b66cf..3af9bc02a255 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 different 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) |
