Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/eld/Config/GeneralOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,19 @@ class GeneralOptions {
return ArchiveMemberReportFile;
}

// --emit-symbol-resolution-report
void setSymbolResolutionReportFile(llvm::StringRef File) {
SymbolResolutionReportFile = File.str();
}

const std::optional<std::string> &getSymbolResolutionReportFile() const {
return SymbolResolutionReportFile;
}

bool shouldEmitSymbolResolutionReport() const {
return SymbolResolutionReportFile.has_value();
}

// --ld-generated-unwind-info
void setGenUnwindInfo(bool PEnable = true) { BGenUnwindInfo = PEnable; }

Expand Down Expand Up @@ -1364,6 +1377,8 @@ class GeneralOptions {
std::optional<std::string> PluginActivityLogFile; // --plugin-activity-file output path
std::optional<std::string>
ArchiveMemberReportFile; // --archive-member-report output path
std::optional<std::string>
SymbolResolutionReportFile; // --emit-symbol-resolution-report output path
std::string MappingFileName; // --Mapping-file
std::string MappingDumpFile; // --dump-mapping-file
std::string ResponseDumpFile; // --dump-response-file
Expand Down
5 changes: 5 additions & 0 deletions include/eld/Core/Linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class Linker {

void printLayout();

/// Emits the JSON symbol resolution report. This function
/// must only be called if symbol resolution report is
/// requested.
bool emitSymbolResolutionReport();

void unloadPlugins();

// Set the GNU linker driver after sniffing
Expand Down
7 changes: 7 additions & 0 deletions include/eld/Driver/GnuLinkerOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -1556,6 +1556,13 @@ defm ArchiveMemberReportFile
MetaVarName<"<filename>">,
Group<grp_miscfeatures>;

defm SymbolResolutionReportFile
: mDashDeprEqWithOpt<"emit-symbol-resolution-report",
"SymbolResolutionReportFile",
"Emit JSON symbol resolution report">,
MetaVarName<"<filename>">,
Group<grp_miscfeatures>;

//===----------------------------------------------------------------------===//
/// Help!
//===----------------------------------------------------------------------===//
Expand Down
7 changes: 1 addition & 6 deletions include/eld/LayoutMap/LayoutInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ class LayoutInfo {
ShowTiming = 0x20,
ShowDebugStrings = 0x40,
ShowRelativePath = 0x80,
ShowInitialLayout = 0x100,
ShowSymbolResolution = 0x200
ShowInitialLayout = 0x100
};

enum InputKindPrefix {
Expand Down Expand Up @@ -419,10 +418,6 @@ class LayoutInfo {

void printStats(void *H, llvm::raw_ostream &OS) const;

bool showSymbolResolution() const {
return LayoutDetail & LayoutDetail::ShowSymbolResolution;
}

private:
Stats LinkStats;
std::vector<std::string> Features;
Expand Down
2 changes: 0 additions & 2 deletions include/eld/LayoutMap/TextLayoutPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ class TextLayoutPrinter {
void printFragments(Module &Module, ELFSection &OutSect, RuleContainer &R,
bool UseColor);

void printSymbolResolution(Module &Module);

void printOffsetHelper(bool HasOffset, std::function<void()> F) const;

private:
Expand Down
2 changes: 2 additions & 0 deletions include/eld/Object/ObjectLinker.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ class ObjectLinker {

bool emitArchiveMemberReport(llvm::StringRef Filename) const;

bool emitSymbolResolutionReport(llvm::StringRef Filename) const;

private:
/// Assigns version nodes to symbols with GNU ld semantics:
/// - Pass 1: Exact matches (forward order, first wins, warns on reassign)
Expand Down
3 changes: 1 addition & 2 deletions include/eld/SymbolResolver/NamePool.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ class NamePool {
DiagnosticPrinter *Printer);

LDSymbol *createPluginSymbol(InputFile *Input, std::string SymbolName,
Fragment *CurFragment, uint64_t Val,
LayoutInfo *layoutInfo);
Fragment *CurFragment, uint64_t Val);

size_t getNumGlobalSize() const { return GlobalSymbols.size(); }

Expand Down
4 changes: 3 additions & 1 deletion include/eld/SymbolResolver/SymbolInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class SymbolInfo {
: SymBinding(0), SymType(0), SymVisibility(0), SymSectIndexKind(0),
IsBitcode(0) {}
unsigned int SymBinding : 2;
// FIXME: SymType needs 4 bits.
unsigned int SymType : 2;
unsigned int SymVisibility : 2;
unsigned int SymSectIndexKind : 3;
Expand All @@ -87,6 +88,7 @@ class SymbolInfo {
void setSymbolSectionIndexKind(ResolveInfo::Binding Binding,
ResolveInfo::Desc SymDesc);
void setBitcodeAttribute(bool IsBitcode);
// FIXME: Is the below bit pattern correct?
/// Information is stored as follows in this bitfield:
/// 0b000000000000000000000sssvvttttbb
/// b: bits used to represent symbol binding.
Expand All @@ -99,4 +101,4 @@ class SymbolInfo {
};
} // namespace eld

#endif
#endif
29 changes: 27 additions & 2 deletions include/eld/SymbolResolver/SymbolResolutionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/JSON.h"
#include <optional>

namespace eld {
Expand All @@ -18,6 +19,7 @@ class GeneralOptions;
class LDSymbol;
class LinkerConfig;
class LinkerScript;
class Module;
class NamePool;
class Plugin;

Expand All @@ -29,8 +31,21 @@ class SymbolResolutionInfo {
using CandidatesTableType = llvm::StringMap<CandidatesType>;
using SymbolInfoMapType = llvm::MapVector<const LDSymbol *, SymbolInfo>;

std::string getSymbolInfoAsString(const LDSymbol *Sym,
const GeneralOptions &Options);
/// Returns the (decorated) section name for a defined symbol, or an empty
/// string when the symbol has no associated section (Undef/Abs/unknown
/// bitcode section).
std::string getSymbolSectionName(const LDSymbol *Sym,
const SymbolInfo &SymInfo,
const GeneralOptions &Options) const;

/// Returns the plugin that provided the symbol, or nullptr for
/// non-plugin symbols.
const Plugin *getSymbolPlugin(const LDSymbol *Sym) const {
auto Iter = SymbolToPluginMap.find(Sym);
if (Iter != SymbolToPluginMap.end())
return Iter->second;
return nullptr;
}

/// Setup symbol resolution candidates information. This information is
/// required for creating symbol resolution report. This function does two
Expand Down Expand Up @@ -61,7 +76,17 @@ class SymbolResolutionInfo {
SymbolToPluginMap[Sym] = Plugin;
}

/// Emits the symbol resolution report as standalone JSON to \p Filename.
/// Returns false (and raises a diagnostic) if the file cannot be written.
bool emitSymbolResolutionReport(Module &CurModule, llvm::StringRef Filename);

private:
/// Builds the JSON object describing a single symbol resolution candidate.
llvm::json::Object buildCandidateObject(const LDSymbol *Candidate,
const SymbolInfo &SymInfo,
const GeneralOptions &Options,
bool IsSelected);

CandidatesTableType Candidates;
SymbolInfoMapType SymbolInfoMap;
std::vector<const LDSymbol *> LTOObjectSymbols;
Expand Down
6 changes: 6 additions & 0 deletions lib/Core/Linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ void Linker::printLayout() {
ObjLinker->printlayout();
}

bool Linker::emitSymbolResolutionReport() {
const GeneralOptions &Options = ThisConfig->options();
return ObjLinker->emitSymbolResolutionReport(
*Options.getSymbolResolutionReportFile());
}

bool Linker::activateInputs(std::vector<InputAction *> &Actions) {
LinkerProgress->incrementAndDisplayProgress();
for (auto &Action : Actions) {
Expand Down
18 changes: 13 additions & 5 deletions lib/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,20 @@ llvm::StringRef Module::getStateStr() const {
void Module::addSymbolCreatedByPluginToFragment(Fragment *F, std::string Symbol,
uint64_t Val,
const eld::Plugin *Plugin) {
LayoutInfo *layoutInfo = getLayoutInfo();
LDSymbol *S = SymbolNamePool.createPluginSymbol(
getInternalInput(Module::InternalInputType::Plugin), Symbol, F, Val,
layoutInfo);
if (S && layoutInfo && layoutInfo->showSymbolResolution())
SymbolNamePool.getSRI().recordPluginSymbol(S, Plugin);
getInternalInput(Module::InternalInputType::Plugin), Symbol, F, Val);
if (S && ThisConfig.options().shouldEmitSymbolResolutionReport()) {
const ResolveInfo *Info = S->resolveInfo();
SymbolResolutionInfo &SRI = SymbolNamePool.getSRI();
SRI.recordSymbolInfo(
S, SymbolInfo{Info->resolvedOrigin(), Info->size(),
static_cast<ResolveInfo::Binding>(Info->binding()),
static_cast<ResolveInfo::Type>(Info->type()),
Info->visibility(),
static_cast<ResolveInfo::Desc>(Info->desc()),
/*isBitcode=*/false});
SRI.recordPluginSymbol(S, Plugin);
}
PluginFragmentToSymbols[F];
PluginFragmentToSymbols[F].push_back(S);
llvm::dyn_cast<eld::ObjectFile>(F->getOwningSection()->getInputFile())
Expand Down
1 change: 0 additions & 1 deletion lib/LayoutMap/LayoutInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ LayoutInfo::setLayoutDetail(llvm::StringRef Option,
.Case("show-timing", ShowTiming)
.Case("show-debug-strings", ShowDebugStrings)
.Case("show-initial-layout", ShowInitialLayout)
.Case("show-symbol-resolution", ShowSymbolResolution)
.StartsWith(ShowRelativePathOptionStr, ShowRelativePath)
.Default(0);
LayoutDetail |= OptionLayoutDetail;
Expand Down
48 changes: 0 additions & 48 deletions lib/LayoutMap/TextLayoutPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1338,9 +1338,6 @@ void TextLayoutPrinter::printMapFile(eld::Module &Module) {

if (!ThisLayoutInfo->showOnlyLayout())
printPluginInfo(Module);

if (ThisLayoutInfo->showSymbolResolution())
printSymbolResolution(Module);
}

void TextLayoutPrinter::printLayout(eld::Module &Module) {
Expand Down Expand Up @@ -1536,51 +1533,6 @@ void TextLayoutPrinter::printFragments(Module &Module, ELFSection &OutSect,
}
}

void TextLayoutPrinter::printSymbolResolution(Module &Module) {
NamePool &NP = Module.getNamePool();
SymbolResolutionInfo &SRI = NP.getSRI();
const auto &Symbols = Module.getSymbols();
const GeneralOptions &Options = ThisLayoutInfo->getConfig().options();
SRI.setupCandidatesInfo(NP, Module.getScript());

outputStream() << "# Symbol Resolution: "
<< "\n";

size_t Index = 0;
for (const auto *RI : Symbols) {
if (RI->isLocal() &&
RI->resolvedOrigin() != Module.getInternalInput(Module::Plugin))
continue;
++Index;
llvm::StringRef SymName = RI->getName();
const SymbolResolutionInfo::CandidatesType Candidates =
SRI.getCandidates(SymName);
outputStream() << Index << ") " << SymName << "\n";
for (const auto &Candidate : Candidates) {
std::optional<SymbolInfo> OptSymbolInfo = SRI.getSymbolInfo(Candidate);
ASSERT(OptSymbolInfo, "Symbol info must be present!");
SymbolInfo CandidateInfo = OptSymbolInfo.value();

std::string CandidateInfoAsString =
SRI.getSymbolInfoAsString(Candidate, Options);
outputStream() << "\t" << CandidateInfoAsString;
if (Candidate->resolveInfo()->outSymbol() == Candidate ||
(CandidateInfo.isBitcodeSymbol() &&
CandidateInfo.getInputFile() ==
Candidate->resolveInfo()->resolvedOrigin()))
outputStream() << " [Selected]";
if (CandidateInfo.isBitcodeSymbol()) {
if (const LDSymbol *LTOSym =
SRI.getCorrespondingLTOObjectSymIfAny(Candidate)) {
outputStream() << "\n\t "
<< SRI.getSymbolInfoAsString(LTOSym, Options);
}
}
outputStream() << "\n";
}
}
}

void TextLayoutPrinter::printOffsetHelper(bool HasOffset,
std::function<void()> F) const {
if (!HasOffset) {
Expand Down
7 changes: 7 additions & 0 deletions lib/LinkerWrapper/GnuLdDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,11 @@ bool GnuLdDriver::processOptions(llvm::opt::InputArgList &Args) {
Config.options().setArchiveMemberReportFile(A->getValue());
}

// --emit-symbol-resolution-report=<file>
if (llvm::opt::Arg *A = Args.getLastArg(T::SymbolResolutionReportFile)) {
Config.options().setSymbolResolutionReportFile(A->getValue());
}

if (Args.hasArg(T::use_old_rule_matching))
Config.options().setUseOldRuleMatching(true);

Expand Down Expand Up @@ -2037,6 +2042,8 @@ bool GnuLdDriver::doLink(llvm::opt::InputArgList &Args,
linkStatus = linker.link();
// llvm::errs() << "link: linkStatus: " << linkStatus << "\n";
linker.printLayout();
if (linkStatus && Config.options().shouldEmitSymbolResolutionReport())
linkStatus &= linker.emitSymbolResolutionReport();
}
if (!linkStatus || Config.options().getRecordInputFiles())
handleReproduce<T>(Args, actions, true);
Expand Down
11 changes: 11 additions & 0 deletions lib/Object/ObjectLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "eld/Object/ObjectLinker.h"
#include "eld/BranchIsland/BranchIslandFactory.h"
#include "eld/Config/GeneralOptions.h"
#include "eld/Config/LinkerConfig.h"
#include "eld/Core/LinkerScript.h"
#include "eld/Core/Module.h"
Expand Down Expand Up @@ -52,6 +53,7 @@
#include "eld/Script/InputSectDesc.h"
#include "eld/Script/OutputSectData.h"
#include "eld/Script/OutputSectDesc.h"
#include "eld/Script/Plugin.h"
#include "eld/Script/ScriptFile.h"
#include "eld/Script/ScriptReader.h"
#include "eld/Script/ScriptSymbol.h"
Expand All @@ -62,7 +64,10 @@
#include "eld/Support/StringRefUtils.h"
#include "eld/Support/Utils.h"
#include "eld/SymbolResolver/IRBuilder.h"
#include "eld/SymbolResolver/LDSymbol.h"
#include "eld/SymbolResolver/NamePool.h"
#include "eld/SymbolResolver/ResolveInfo.h"
#include "eld/SymbolResolver/SymbolResolutionInfo.h"
#include "eld/Target/GNULDBackend.h"
#include "eld/Target/LDFileFormat.h"
#include "eld/Target/Relocator.h"
Expand All @@ -85,6 +90,7 @@
#include "llvm/Support/raw_ostream.h"
#include <chrono>
#include <mutex>
#include <optional>
#include <sstream>
#include <unordered_set>

Expand Down Expand Up @@ -160,6 +166,11 @@ bool ObjectLinker::emitArchiveMemberReport(llvm::StringRef Filename) const {
ThisConfig.getDiagEngine());
}

bool ObjectLinker::emitSymbolResolutionReport(llvm::StringRef Filename) const {
return ThisModule->getNamePool().getSRI().emitSymbolResolutionReport(
*ThisModule, Filename);
}

/// initStdSections - initialize standard sections
bool ObjectLinker::initStdSections() {
ObjectBuilder Builder(ThisConfig, *ThisModule);
Expand Down
9 changes: 3 additions & 6 deletions lib/SymbolResolver/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ LDSymbol *IRBuilder::addSymbolFromObject(
return InputSym;
}

if (ThisModule.getLayoutInfo() &&
ThisModule.getLayoutInfo()->showSymbolResolution())
if (ThisModule.getConfig().options().shouldEmitSymbolResolutionReport())
NP.getSRI().recordSymbolInfo(InputSym, SymInfo);

bool S = NP.insertNonLocalSymbol(InputSymbolResolveInfo, *InputSym,
Expand Down Expand Up @@ -336,8 +335,7 @@ LDSymbol *IRBuilder::addSymbolFromDynObj(
InputSym->setSectionIndex(Shndx);
InputSym->setSymbolIndex(SymIdx);

if (ThisModule.getLayoutInfo() &&
ThisModule.getLayoutInfo()->showSymbolResolution())
if (ThisModule.getConfig().options().shouldEmitSymbolResolutionReport())
ThisModule.getNamePool().getSRI().recordSymbolInfo(InputSym, SymInfo);

Resolver::Result ResolvedResult = {nullptr, false, false};
Expand Down Expand Up @@ -572,8 +570,7 @@ LDSymbol *IRBuilder::addSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
OutputSym->setValue(Value, false);
}

if (ThisModule.getLayoutInfo() &&
ThisModule.getLayoutInfo()->showSymbolResolution()) {
if (ThisModule.getConfig().options().shouldEmitSymbolResolutionReport()) {
SymbolResolutionInfo &SRI = ThisModule.getNamePool().getSRI();
SRI.recordSymbolInfo(OutputSym,
SymbolInfo{Input, Size, Binding, Type, Visibility,
Expand Down
Loading
Loading