Skip to content

Commit 1f13713

Browse files
committed
[ELF] Change getSrcMsg to use ELFSyncStream. NFC
1 parent 04ab599 commit 1f13713

File tree

8 files changed

+66
-60
lines changed

8 files changed

+66
-60
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -367,39 +367,6 @@ void elf::parseFiles(Ctx &ctx,
367367
}
368368

369369
// Concatenates arguments to construct a string representing an error location.
370-
static std::string createFileLineMsg(StringRef path, unsigned line) {
371-
std::string filename = std::string(path::filename(path));
372-
std::string lineno = ":" + std::to_string(line);
373-
if (filename == path)
374-
return filename + lineno;
375-
return filename + lineno + " (" + path.str() + lineno + ")";
376-
}
377-
378-
std::string InputFile::getSrcMsg(const InputSectionBase &sec, const Symbol &sym,
379-
uint64_t offset) {
380-
if (kind() != ObjKind)
381-
return "";
382-
383-
// First, look up the DWARF line table.
384-
ArrayRef<InputSectionBase *> sections = getSections();
385-
auto it = llvm::find(sections, &sec);
386-
uint64_t sectionIndex = it != sections.end()
387-
? it - sections.begin()
388-
: object::SectionedAddress::UndefSection;
389-
DWARFCache *dwarf = cast<ELFFileBase>(this)->getDwarf();
390-
if (std::optional<DILineInfo> info =
391-
dwarf->getDILineInfo(offset, sectionIndex))
392-
return createFileLineMsg(info->FileName, info->Line);
393-
394-
// If it failed, look up again as a variable.
395-
if (std::optional<std::pair<std::string, unsigned>> fileLine =
396-
dwarf->getVariableLoc(sym.getName()))
397-
return createFileLineMsg(fileLine->first, fileLine->second);
398-
399-
// File.sourceFile contains STT_FILE symbol, and that is a last resort.
400-
return std::string(cast<ELFFileBase>(this)->sourceFile);
401-
}
402-
403370
StringRef InputFile::getNameForScript() const {
404371
if (archiveName.empty())
405372
return getName();

lld/ELF/InputFiles.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ class InputFile {
147147
// True if this is an argument for --just-symbols. Usually false.
148148
bool justSymbols = false;
149149

150-
std::string getSrcMsg(const InputSectionBase &sec, const Symbol &sym,
151-
uint64_t offset);
152-
153150
// On PPC64 we need to keep track of which files contain small code model
154151
// relocations that access the .toc section. To minimize the chance of a
155152
// relocation overflow, files that do contain said relocations should have

lld/ELF/InputSection.cpp

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "SyntheticSections.h"
1717
#include "Target.h"
1818
#include "lld/Common/CommonLinkerContext.h"
19+
#include "lld/Common/DWARF.h"
1920
#include "llvm/Support/Compiler.h"
2021
#include "llvm/Support/Compression.h"
2122
#include "llvm/Support/Endian.h"
@@ -316,15 +317,40 @@ std::string InputSectionBase::getLocation(uint64_t offset) const {
316317
return filename + ":(" + secAndOffset;
317318
}
318319

319-
// This function is intended to be used for constructing an error message.
320-
// The returned message looks like this:
320+
static void printFileLine(const ELFSyncStream &s, StringRef path,
321+
unsigned line) {
322+
StringRef filename = path::filename(path);
323+
s << filename << ':' << line;
324+
if (filename != path)
325+
s << " (" << path << ':' << line << ')';
326+
}
327+
328+
// Print an error message that looks like this:
321329
//
322330
// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
323-
//
324-
// Returns an empty string if there's no way to get line info.
325-
std::string InputSectionBase::getSrcMsg(const Symbol &sym,
326-
uint64_t offset) const {
327-
return file->getSrcMsg(*this, sym, offset);
331+
const ELFSyncStream &elf::operator<<(const ELFSyncStream &s,
332+
InputSectionBase::SrcMsg &&msg) {
333+
auto &sec = msg.sec;
334+
if (sec.file->kind() != InputFile::ObjKind)
335+
return s;
336+
auto &file = cast<ELFFileBase>(*sec.file);
337+
338+
// First, look up the DWARF line table.
339+
ArrayRef<InputSectionBase *> sections = file.getSections();
340+
auto it = llvm::find(sections, &sec);
341+
uint64_t sectionIndex = it != sections.end()
342+
? it - sections.begin()
343+
: object::SectionedAddress::UndefSection;
344+
DWARFCache *dwarf = file.getDwarf();
345+
if (auto info = dwarf->getDILineInfo(msg.offset, sectionIndex))
346+
printFileLine(s, info->FileName, info->Line);
347+
else if (auto fileLine = dwarf->getVariableLoc(msg.sym.getName()))
348+
// If it failed, look up again as a variable.
349+
printFileLine(s, fileLine->first, fileLine->second);
350+
else
351+
// File.sourceFile contains STT_FILE symbol, and that is a last resort.
352+
s << file.sourceFile;
353+
return s;
328354
}
329355

330356
// Returns a filename string along with an optional section name. This

lld/ELF/InputSection.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ class InputSectionBase : public SectionBase {
147147
const InputSectionBase *sec;
148148
uint64_t offset;
149149
};
150+
struct SrcMsg {
151+
const InputSectionBase &sec;
152+
const Symbol &sym;
153+
uint64_t offset;
154+
};
150155

151156
template <class ELFT>
152157
InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header,
@@ -252,8 +257,10 @@ class InputSectionBase : public SectionBase {
252257

253258
// Returns a source location string. Used to construct an error message.
254259
std::string getLocation(uint64_t offset) const;
255-
std::string getSrcMsg(const Symbol &sym, uint64_t offset) const;
256260
ObjMsg getObjMsg(uint64_t offset) const { return {this, offset}; }
261+
SrcMsg getSrcMsg(const Symbol &sym, uint64_t offset) const {
262+
return {*this, sym, offset};
263+
}
257264

258265
// Each section knows how to relocate itself. These functions apply
259266
// relocations, assuming that Buf points to this section's copy in
@@ -522,6 +529,8 @@ const ELFSyncStream &operator<<(const ELFSyncStream &,
522529
const InputSectionBase *);
523530
const ELFSyncStream &operator<<(const ELFSyncStream &,
524531
InputSectionBase::ObjMsg &&);
532+
const ELFSyncStream &operator<<(const ELFSyncStream &,
533+
InputSectionBase::SrcMsg &&);
525534
} // namespace elf
526535
} // namespace lld
527536

lld/ELF/Relocations.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ static void printLocation(ELFSyncStream &s, InputSectionBase &sec,
9191
const Symbol &sym, uint64_t off) {
9292
printDefinedLocation(s, sym);
9393
s << "\n>>> referenced by ";
94-
std::string src = sec.getSrcMsg(sym, off);
95-
if (!src.empty())
96-
s << src << "\n>>> ";
94+
auto tell = s.tell();
95+
s << sec.getSrcMsg(sym, off);
96+
if (tell != s.tell())
97+
s << "\n>>> ";
9798
s << sec.getObjMsg(off);
9899
}
99100

@@ -738,9 +739,12 @@ static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
738739
// In the absence of line number information, utilize DW_TAG_variable (if
739740
// present) for the enclosing symbol (e.g. var in `int *a[] = {&undef};`).
740741
Symbol *enclosing = sec.getEnclosingSymbol(offset);
741-
std::string src = sec.getSrcMsg(enclosing ? *enclosing : sym, offset);
742-
if (!src.empty())
743-
msg << src << "\n>>> ";
742+
743+
ELFSyncStream msg1(ctx, DiagLevel::None);
744+
auto tell = msg.tell();
745+
msg << sec.getSrcMsg(enclosing ? *enclosing : sym, offset);
746+
if (tell != msg.tell())
747+
msg << "\n>>> ";
744748
msg << sec.getObjMsg(offset);
745749
}
746750

lld/ELF/Symbols.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -543,16 +543,17 @@ void elf::reportDuplicate(Ctx &ctx, const Symbol &sym, const InputFile *newFile,
543543
// >>> defined at baz.c:563
544544
// >>> baz.o in archive libbaz.a
545545
auto *sec1 = cast<InputSectionBase>(d->section);
546-
std::string src1 = sec1->getSrcMsg(sym, d->value);
547-
std::string src2 = errSec->getSrcMsg(sym, errOffset);
548-
549546
auto diag = Err(ctx);
550547
diag << "duplicate symbol: " << &sym << "\n>>> defined at ";
551-
if (!src1.empty())
552-
diag << src1 << "\n>>> ";
548+
auto tell = diag.tell();
549+
diag << sec1->getSrcMsg(sym, d->value);
550+
if (tell != diag.tell())
551+
diag << "\n>>> ";
553552
diag << sec1->getObjMsg(d->value) << "\n>>> defined at ";
554-
if (!src2.empty())
555-
diag << src2 << "\n>>> ";
553+
tell = diag.tell();
554+
diag << errSec->getSrcMsg(sym, errOffset);
555+
if (tell != diag.tell())
556+
diag << "\n>>> ";
556557
diag << errSec->getObjMsg(errOffset);
557558
}
558559

lld/ELF/Target.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,11 @@ ErrorPlace elf::getErrorPlace(Ctx &ctx, const uint8_t *loc) {
106106
if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
107107
std::string objLoc = isec->getLocation(loc - isecLoc);
108108
// Return object file location and source file location.
109-
// TODO: Refactor getSrcMsg not to take a variable.
110109
Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
111-
return {isec, objLoc + ": ",
112-
isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
110+
ELFSyncStream msg(ctx, DiagLevel::None);
111+
if (isec->file)
112+
msg << isec->getSrcMsg(dummy, loc - isecLoc);
113+
return {isec, objLoc + ": ", std::string(msg.str())};
113114
}
114115
}
115116
return {};

lld/include/lld/Common/ErrorHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class SyncStream {
167167
SyncStream(SyncStream &&o) : e(o.e), level(o.level), buf(std::move(o.buf)) {}
168168
~SyncStream();
169169
StringRef str() { return os.str(); }
170+
uint64_t tell() { return os.tell(); }
170171
};
171172

172173
[[noreturn]] void exitLld(int val);

0 commit comments

Comments
 (0)