|
16 | 16 | #include "SyntheticSections.h" |
17 | 17 | #include "Target.h" |
18 | 18 | #include "lld/Common/CommonLinkerContext.h" |
| 19 | +#include "lld/Common/DWARF.h" |
19 | 20 | #include "llvm/Support/Compiler.h" |
20 | 21 | #include "llvm/Support/Compression.h" |
21 | 22 | #include "llvm/Support/Endian.h" |
@@ -316,15 +317,40 @@ std::string InputSectionBase::getLocation(uint64_t offset) const { |
316 | 317 | return filename + ":(" + secAndOffset; |
317 | 318 | } |
318 | 319 |
|
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: |
321 | 329 | // |
322 | 330 | // 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; |
328 | 354 | } |
329 | 355 |
|
330 | 356 | // Returns a filename string along with an optional section name. This |
|
0 commit comments