Skip to content

Commit 666de79

Browse files
committed
[ELF] Move some ObjFile members to ELFFileBase to simplify getSrcMsg
1 parent 8ac2b77 commit 666de79

File tree

3 files changed

+59
-80
lines changed

3 files changed

+59
-80
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 41 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -375,39 +375,29 @@ static std::string createFileLineMsg(StringRef path, unsigned line) {
375375
return filename + lineno + " (" + path.str() + lineno + ")";
376376
}
377377

378-
template <class ELFT>
379-
static std::string getSrcMsgAux(ObjFile<ELFT> &file, const Symbol &sym,
380-
const InputSectionBase &sec, uint64_t offset) {
381-
// In DWARF, functions and variables are stored to different places.
382-
// First, look up a function for a given offset.
383-
if (std::optional<DILineInfo> info = file.getDILineInfo(&sec, offset))
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))
384392
return createFileLineMsg(info->FileName, info->Line);
385393

386394
// If it failed, look up again as a variable.
387395
if (std::optional<std::pair<std::string, unsigned>> fileLine =
388-
file.getVariableLoc(sym.getName()))
396+
dwarf->getVariableLoc(sym.getName()))
389397
return createFileLineMsg(fileLine->first, fileLine->second);
390398

391399
// File.sourceFile contains STT_FILE symbol, and that is a last resort.
392-
return std::string(file.sourceFile);
393-
}
394-
395-
std::string InputFile::getSrcMsg(const Symbol &sym, const InputSectionBase &sec,
396-
uint64_t offset) {
397-
if (kind() != ObjKind)
398-
return "";
399-
switch (ekind) {
400-
default:
401-
llvm_unreachable("Invalid kind");
402-
case ELF32LEKind:
403-
return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), sym, sec, offset);
404-
case ELF32BEKind:
405-
return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), sym, sec, offset);
406-
case ELF64LEKind:
407-
return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), sym, sec, offset);
408-
case ELF64BEKind:
409-
return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), sym, sec, offset);
410-
}
400+
return std::string(cast<ELFFileBase>(this)->sourceFile);
411401
}
412402

413403
StringRef InputFile::getNameForScript() const {
@@ -480,50 +470,41 @@ static void handleSectionGroup(ArrayRef<InputSectionBase *> sections,
480470
prev->nextInSectionGroup = head;
481471
}
482472

483-
template <class ELFT> DWARFCache *ObjFile<ELFT>::getDwarf() {
484-
llvm::call_once(initDwarf, [this]() {
485-
dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>(
486-
std::make_unique<LLDDwarfObj<ELFT>>(this), "",
487-
[&](Error err) { Warn(ctx) << getName() + ": " << std::move(err); },
488-
[&](Error warning) {
489-
Warn(ctx) << getName() << ": " << std::move(warning);
490-
}));
491-
});
492-
493-
return dwarf.get();
473+
template <class ELFT> void ObjFile<ELFT>::initDwarf() {
474+
dwarf = std::make_unique<DWARFCache>(std::make_unique<DWARFContext>(
475+
std::make_unique<LLDDwarfObj<ELFT>>(this), "",
476+
[&](Error err) { Warn(ctx) << getName() + ": " << std::move(err); },
477+
[&](Error warning) {
478+
Warn(ctx) << getName() << ": " << std::move(warning);
479+
}));
494480
}
495481

496-
// Returns the pair of file name and line number describing location of data
497-
// object (variable, array, etc) definition.
498-
template <class ELFT>
499-
std::optional<std::pair<std::string, unsigned>>
500-
ObjFile<ELFT>::getVariableLoc(StringRef name) {
501-
return getDwarf()->getVariableLoc(name);
502-
}
503-
504-
// Returns source line information for a given offset
505-
// using DWARF debug info.
506-
template <class ELFT>
507-
std::optional<DILineInfo>
508-
ObjFile<ELFT>::getDILineInfo(const InputSectionBase *s, uint64_t offset) {
509-
// Detect SectionIndex for specified section.
510-
uint64_t sectionIndex = object::SectionedAddress::UndefSection;
511-
ArrayRef<InputSectionBase *> sections = s->file->getSections();
512-
for (uint64_t curIndex = 0; curIndex < sections.size(); ++curIndex) {
513-
if (s == sections[curIndex]) {
514-
sectionIndex = curIndex;
515-
break;
482+
DWARFCache *ELFFileBase::getDwarf() {
483+
assert(fileKind == ObjKind);
484+
llvm::call_once(initDwarf, [this]() {
485+
switch (ekind) {
486+
default:
487+
llvm_unreachable("");
488+
case ELF32LEKind:
489+
return cast<ObjFile<ELF32LE>>(this)->initDwarf();
490+
case ELF32BEKind:
491+
return cast<ObjFile<ELF32BE>>(this)->initDwarf();
492+
case ELF64LEKind:
493+
return cast<ObjFile<ELF64LE>>(this)->initDwarf();
494+
case ELF64BEKind:
495+
return cast<ObjFile<ELF64BE>>(this)->initDwarf();
516496
}
517-
}
518-
519-
return getDwarf()->getDILineInfo(offset, sectionIndex);
497+
});
498+
return dwarf.get();
520499
}
521500

522501
ELFFileBase::ELFFileBase(Ctx &ctx, Kind k, ELFKind ekind, MemoryBufferRef mb)
523502
: InputFile(ctx, k, mb) {
524503
this->ekind = ekind;
525504
}
526505

506+
ELFFileBase::~ELFFileBase() {}
507+
527508
template <typename Elf_Shdr>
528509
static const Elf_Shdr *findSection(ArrayRef<Elf_Shdr> sections, uint32_t type) {
529510
for (const Elf_Shdr &sec : sections)

lld/ELF/InputFiles.h

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

150-
std::string getSrcMsg(const Symbol &sym, const InputSectionBase &sec,
150+
std::string getSrcMsg(const InputSectionBase &sec, const Symbol &sym,
151151
uint64_t offset);
152152

153153
// On PPC64 we need to keep track of which files contain small code model
@@ -181,6 +181,7 @@ class InputFile {
181181
class ELFFileBase : public InputFile {
182182
public:
183183
ELFFileBase(Ctx &ctx, Kind k, ELFKind ekind, MemoryBufferRef m);
184+
~ELFFileBase();
184185
static bool classof(const InputFile *f) { return f->isElf(); }
185186

186187
void init();
@@ -216,6 +217,9 @@ class ELFFileBase : public InputFile {
216217
return getELFSyms<ELFT>().slice(firstGlobal);
217218
}
218219

220+
// Get cached DWARF information.
221+
DWARFCache *getDwarf();
222+
219223
protected:
220224
// Initializes this class's member variables.
221225
template <typename ELFT> void init(InputFile::Kind k);
@@ -227,7 +231,18 @@ class ELFFileBase : public InputFile {
227231
uint32_t numELFSyms = 0;
228232
uint32_t firstGlobal = 0;
229233

234+
// Below are ObjFile specific members.
235+
236+
// Debugging information to retrieve source file and line for error
237+
// reporting. Linker may find reasonable number of errors in a
238+
// single object file, so we cache debugging information in order to
239+
// parse it only once for each object file we link.
240+
llvm::once_flag initDwarf;
241+
std::unique_ptr<DWARFCache> dwarf;
242+
230243
public:
244+
// Name of source file obtained from STT_FILE, if present.
245+
StringRef sourceFile;
231246
uint32_t andFeatures = 0;
232247
bool hasCommonSyms = false;
233248
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
@@ -257,15 +272,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
257272

258273
uint32_t getSectionIndex(const Elf_Sym &sym) const;
259274

260-
std::optional<llvm::DILineInfo> getDILineInfo(const InputSectionBase *,
261-
uint64_t);
262-
std::optional<std::pair<std::string, unsigned>>
263-
getVariableLoc(StringRef name);
264-
265-
// Name of source file obtained from STT_FILE symbol value,
266-
// or empty string if there is no such symbol in object file
267-
// symbol table.
268-
StringRef sourceFile;
269275

270276
// Pointer to this input file's .llvm_addrsig section, if it has one.
271277
const Elf_Shdr *addrsigSec = nullptr;
@@ -286,8 +292,7 @@ template <class ELFT> class ObjFile : public ELFFileBase {
286292
// but had one or more functions with the no_split_stack attribute.
287293
bool someNoSplitStack = false;
288294

289-
// Get cached DWARF information.
290-
DWARFCache *getDwarf();
295+
void initDwarf();
291296

292297
void initSectionsAndLocalSyms(bool ignoreComdats);
293298
void postParse();
@@ -318,13 +323,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
318323
// The following variable contains the contents of .symtab_shndx.
319324
// If the section does not exist (which is common), the array is empty.
320325
ArrayRef<Elf_Word> shndxTable;
321-
322-
// Debugging information to retrieve source file and line for error
323-
// reporting. Linker may find reasonable number of errors in a
324-
// single object file, so we cache debugging information in order to
325-
// parse it only once for each object file we link.
326-
std::unique_ptr<DWARFCache> dwarf;
327-
llvm::once_flag initDwarf;
328326
};
329327

330328
class BitcodeFile : public InputFile {

lld/ELF/InputSection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ std::string InputSectionBase::getLocation(uint64_t offset) const {
324324
// Returns an empty string if there's no way to get line info.
325325
std::string InputSectionBase::getSrcMsg(const Symbol &sym,
326326
uint64_t offset) const {
327-
return file->getSrcMsg(sym, *this, offset);
327+
return file->getSrcMsg(*this, sym, offset);
328328
}
329329

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

0 commit comments

Comments
 (0)