summaryrefslogtreecommitdiff
path: root/lld/ELF/InputFiles.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2024-11-29 15:48:46 -0800
committerFangrui Song <i@maskray.me>2024-11-29 15:48:46 -0800
commit666de79595dc2460b7abca0b99d79d058c10cadf (patch)
tree8adebdf5694fd0a4df4862e3c5b83f9d2a3ea27d /lld/ELF/InputFiles.cpp
parent8ac2b77a11c9db9879557ce1c26e38628e1ef45f (diff)
[ELF] Move some ObjFile members to ELFFileBase to simplify getSrcMsg
Diffstat (limited to 'lld/ELF/InputFiles.cpp')
-rw-r--r--lld/ELF/InputFiles.cpp101
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)