[lld] 1f13713 - [ELF] Change getSrcMsg to use ELFSyncStream. NFC
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 29 17:18:28 PST 2024
Author: Fangrui Song
Date: 2024-11-29T17:18:22-08:00
New Revision: 1f13713dbb323d678c37efd5aa98a69e8f633b26
URL: https://github.com/llvm/llvm-project/commit/1f13713dbb323d678c37efd5aa98a69e8f633b26
DIFF: https://github.com/llvm/llvm-project/commit/1f13713dbb323d678c37efd5aa98a69e8f633b26.diff
LOG: [ELF] Change getSrcMsg to use ELFSyncStream. NFC
Added:
Modified:
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/InputSection.cpp
lld/ELF/InputSection.h
lld/ELF/Relocations.cpp
lld/ELF/Symbols.cpp
lld/ELF/Target.cpp
lld/include/lld/Common/ErrorHandler.h
Removed:
################################################################################
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 3af9bc02a255a6..30fbb5d9fe4527 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -367,39 +367,6 @@ void elf::parseFiles(Ctx &ctx,
}
// Concatenates arguments to construct a string representing an error location.
-static std::string createFileLineMsg(StringRef path, unsigned line) {
- std::string filename = std::string(path::filename(path));
- std::string lineno = ":" + std::to_string(line);
- if (filename == path)
- return filename + lineno;
- return filename + lineno + " (" + path.str() + lineno + ")";
-}
-
-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 =
- 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(cast<ELFFileBase>(this)->sourceFile);
-}
-
StringRef InputFile::getNameForScript() const {
if (archiveName.empty())
return getName();
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index b567cda6831293..79545c4bdeb5d0 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -147,9 +147,6 @@ class InputFile {
// True if this is an argument for --just-symbols. Usually false.
bool justSymbols = false;
- 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
// relocations that access the .toc section. To minimize the chance of a
// relocation overflow, files that do contain said relocations should have
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 48facf3312b0c5..51065b63f7b83a 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -16,6 +16,7 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/CommonLinkerContext.h"
+#include "lld/Common/DWARF.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
@@ -316,15 +317,40 @@ std::string InputSectionBase::getLocation(uint64_t offset) const {
return filename + ":(" + secAndOffset;
}
-// This function is intended to be used for constructing an error message.
-// The returned message looks like this:
+static void printFileLine(const ELFSyncStream &s, StringRef path,
+ unsigned line) {
+ StringRef filename = path::filename(path);
+ s << filename << ':' << line;
+ if (filename != path)
+ s << " (" << path << ':' << line << ')';
+}
+
+// Print an error message that looks like this:
//
// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
-//
-// 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(*this, sym, offset);
+const ELFSyncStream &elf::operator<<(const ELFSyncStream &s,
+ InputSectionBase::SrcMsg &&msg) {
+ auto &sec = msg.sec;
+ if (sec.file->kind() != InputFile::ObjKind)
+ return s;
+ auto &file = cast<ELFFileBase>(*sec.file);
+
+ // First, look up the DWARF line table.
+ ArrayRef<InputSectionBase *> sections = file.getSections();
+ auto it = llvm::find(sections, &sec);
+ uint64_t sectionIndex = it != sections.end()
+ ? it - sections.begin()
+ : object::SectionedAddress::UndefSection;
+ DWARFCache *dwarf = file.getDwarf();
+ if (auto info = dwarf->getDILineInfo(msg.offset, sectionIndex))
+ printFileLine(s, info->FileName, info->Line);
+ else if (auto fileLine = dwarf->getVariableLoc(msg.sym.getName()))
+ // If it failed, look up again as a variable.
+ printFileLine(s, fileLine->first, fileLine->second);
+ else
+ // File.sourceFile contains STT_FILE symbol, and that is a last resort.
+ s << file.sourceFile;
+ return s;
}
// Returns a filename string along with an optional section name. This
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 91678aeeaf7671..60988dfacbd746 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -147,6 +147,11 @@ class InputSectionBase : public SectionBase {
const InputSectionBase *sec;
uint64_t offset;
};
+ struct SrcMsg {
+ const InputSectionBase &sec;
+ const Symbol &sym;
+ uint64_t offset;
+ };
template <class ELFT>
InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header,
@@ -252,8 +257,10 @@ class InputSectionBase : public SectionBase {
// Returns a source location string. Used to construct an error message.
std::string getLocation(uint64_t offset) const;
- std::string getSrcMsg(const Symbol &sym, uint64_t offset) const;
ObjMsg getObjMsg(uint64_t offset) const { return {this, offset}; }
+ SrcMsg getSrcMsg(const Symbol &sym, uint64_t offset) const {
+ return {*this, sym, offset};
+ }
// Each section knows how to relocate itself. These functions apply
// relocations, assuming that Buf points to this section's copy in
@@ -522,6 +529,8 @@ const ELFSyncStream &operator<<(const ELFSyncStream &,
const InputSectionBase *);
const ELFSyncStream &operator<<(const ELFSyncStream &,
InputSectionBase::ObjMsg &&);
+const ELFSyncStream &operator<<(const ELFSyncStream &,
+ InputSectionBase::SrcMsg &&);
} // namespace elf
} // namespace lld
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index d311dba41741c0..605321b3cc9e3f 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -91,9 +91,10 @@ static void printLocation(ELFSyncStream &s, InputSectionBase &sec,
const Symbol &sym, uint64_t off) {
printDefinedLocation(s, sym);
s << "\n>>> referenced by ";
- std::string src = sec.getSrcMsg(sym, off);
- if (!src.empty())
- s << src << "\n>>> ";
+ auto tell = s.tell();
+ s << sec.getSrcMsg(sym, off);
+ if (tell != s.tell())
+ s << "\n>>> ";
s << sec.getObjMsg(off);
}
@@ -738,9 +739,12 @@ static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
// In the absence of line number information, utilize DW_TAG_variable (if
// present) for the enclosing symbol (e.g. var in `int *a[] = {&undef};`).
Symbol *enclosing = sec.getEnclosingSymbol(offset);
- std::string src = sec.getSrcMsg(enclosing ? *enclosing : sym, offset);
- if (!src.empty())
- msg << src << "\n>>> ";
+
+ ELFSyncStream msg1(ctx, DiagLevel::None);
+ auto tell = msg.tell();
+ msg << sec.getSrcMsg(enclosing ? *enclosing : sym, offset);
+ if (tell != msg.tell())
+ msg << "\n>>> ";
msg << sec.getObjMsg(offset);
}
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 82215f305978f2..444ed5e69d362b 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -543,16 +543,17 @@ void elf::reportDuplicate(Ctx &ctx, const Symbol &sym, const InputFile *newFile,
// >>> defined at baz.c:563
// >>> baz.o in archive libbaz.a
auto *sec1 = cast<InputSectionBase>(d->section);
- std::string src1 = sec1->getSrcMsg(sym, d->value);
- std::string src2 = errSec->getSrcMsg(sym, errOffset);
-
auto diag = Err(ctx);
diag << "duplicate symbol: " << &sym << "\n>>> defined at ";
- if (!src1.empty())
- diag << src1 << "\n>>> ";
+ auto tell = diag.tell();
+ diag << sec1->getSrcMsg(sym, d->value);
+ if (tell != diag.tell())
+ diag << "\n>>> ";
diag << sec1->getObjMsg(d->value) << "\n>>> defined at ";
- if (!src2.empty())
- diag << src2 << "\n>>> ";
+ tell = diag.tell();
+ diag << errSec->getSrcMsg(sym, errOffset);
+ if (tell != diag.tell())
+ diag << "\n>>> ";
diag << errSec->getObjMsg(errOffset);
}
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 63d813e550f938..c90ef8505aaddb 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -106,10 +106,11 @@ ErrorPlace elf::getErrorPlace(Ctx &ctx, const uint8_t *loc) {
if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
std::string objLoc = isec->getLocation(loc - isecLoc);
// Return object file location and source file location.
- // TODO: Refactor getSrcMsg not to take a variable.
Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
- return {isec, objLoc + ": ",
- isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
+ ELFSyncStream msg(ctx, DiagLevel::None);
+ if (isec->file)
+ msg << isec->getSrcMsg(dummy, loc - isecLoc);
+ return {isec, objLoc + ": ", std::string(msg.str())};
}
}
return {};
diff --git a/lld/include/lld/Common/ErrorHandler.h b/lld/include/lld/Common/ErrorHandler.h
index 79e20be2bb6be8..4db1fec268d766 100644
--- a/lld/include/lld/Common/ErrorHandler.h
+++ b/lld/include/lld/Common/ErrorHandler.h
@@ -167,6 +167,7 @@ class SyncStream {
SyncStream(SyncStream &&o) : e(o.e), level(o.level), buf(std::move(o.buf)) {}
~SyncStream();
StringRef str() { return os.str(); }
+ uint64_t tell() { return os.tell(); }
};
[[noreturn]] void exitLld(int val);
More information about the llvm-commits
mailing list