using namespace llvm;
using namespace llvm::jitlink;
+static bool isELFGOTSection(Section &S) { return S.getName() == "$__GOT"; }
+
+static bool isELFStubsSection(Section &S) { return S.getName() == "$__STUBS"; }
+
+static Expected<Edge &> getFirstRelocationEdge(LinkGraph &G, Block &B) {
+ auto EItr = std::find_if(B.edges().begin(), B.edges().end(),
+ [](Edge &E) { return E.isRelocation(); });
+ if (EItr == B.edges().end())
+ return make_error<StringError>("GOT entry in " + G.getName() + ", \"" +
+ B.getSection().getName() +
+ "\" has no relocations",
+ inconvertibleErrorCode());
+ return *EItr;
+}
+
+static Expected<Symbol &> getELFGOTTarget(LinkGraph &G, Block &B) {
+ auto E = getFirstRelocationEdge(G, B);
+ if (!E)
+ return E.takeError();
+ auto &TargetSym = E->getTarget();
+ if (!TargetSym.hasName())
+ return make_error<StringError>(
+ "GOT entry in " + G.getName() + ", \"" +
+ TargetSym.getBlock().getSection().getName() +
+ "\" points to anonymous "
+ "symbol",
+ inconvertibleErrorCode());
+ return TargetSym;
+}
+
+static Expected<Symbol &> getELFStubTarget(LinkGraph &G, Block &B) {
+ auto E = getFirstRelocationEdge(G, B);
+ if (!E)
+ return E.takeError();
+ auto &GOTSym = E->getTarget();
+ if (!GOTSym.isDefined() || !isELFGOTSection(GOTSym.getBlock().getSection()))
+ return make_error<StringError>(
+ "Stubs entry in " + G.getName() + ", \"" +
+ GOTSym.getBlock().getSection().getName() +
+ "\" does not point to GOT entry",
+ inconvertibleErrorCode());
+ return getELFGOTTarget(G, GOTSym.getBlock());
+}
+
namespace llvm {
Error registerELFGraphInfo(Session &S, LinkGraph &G) {
"\"",
inconvertibleErrorCode());
+ bool isGOTSection = isELFGOTSection(Sec);
+ bool isStubsSection = isELFStubsSection(Sec);
+
bool SectionContainsContent = false;
bool SectionContainsZeroFill = false;
if (Sym->getAddress() > LastSym->getAddress())
LastSym = Sym;
- if (Sym->hasName()) {
+ if (isGOTSection) {
+ if (Sym->isSymbolZeroFill())
+ return make_error<StringError>("zero-fill atom in GOT section",
+ inconvertibleErrorCode());
+
+ if (auto TS = getELFGOTTarget(G, Sym->getBlock()))
+ FileInfo.GOTEntryInfos[TS->getName()] = {Sym->getSymbolContent(),
+ Sym->getAddress()};
+ else
+ return TS.takeError();
+ SectionContainsContent = true;
+ } else if (isStubsSection) {
+ if (Sym->isSymbolZeroFill())
+ return make_error<StringError>("zero-fill atom in Stub section",
+ inconvertibleErrorCode());
+
+ if (auto TS = getELFStubTarget(G, Sym->getBlock()))
+ FileInfo.StubInfos[TS->getName()] = {Sym->getSymbolContent(),
+ Sym->getAddress()};
+ else
+ return TS.takeError();
+ SectionContainsContent = true;
+ } else if (Sym->hasName()) {
dbgs() << "Symbol: " << Sym->getName() << "\n";
if (Sym->isSymbolZeroFill()) {
S.SymbolInfos[Sym->getName()] = {Sym->getSize(), Sym->getAddress()};