mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 05:26:31 +00:00
[ELF] Change getSrcMsg to use ELFSyncStream. NFC
This commit is contained in:
parent
04ab599363
commit
1f13713dbb
@ -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();
|
||||
|
@ -147,9 +147,6 @@ public:
|
||||
// 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
|
||||
|
@ -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
|
||||
|
@ -147,6 +147,11 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
// 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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {};
|
||||
|
@ -167,6 +167,7 @@ public:
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user