From 3b55bfad2a3b7dba8815e043fcd9a2c0cb7b2987 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 17 Jul 2020 14:56:51 -0700 Subject: [PATCH] [llvm-jitlink] Add suppport for testing GOT entries and stubs for ELF. This enables regression testing of GOT and stub handling with llvm-jitlink. --- llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp | 71 +++++++++++++++++++++++++- llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp | 6 --- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp index 1b74f10..beb73fb 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp @@ -20,6 +20,50 @@ 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 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("GOT entry in " + G.getName() + ", \"" + + B.getSection().getName() + + "\" has no relocations", + inconvertibleErrorCode()); + return *EItr; +} + +static Expected 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( + "GOT entry in " + G.getName() + ", \"" + + TargetSym.getBlock().getSection().getName() + + "\" points to anonymous " + "symbol", + inconvertibleErrorCode()); + return TargetSym; +} + +static Expected 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( + "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) { @@ -53,6 +97,9 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) { "\"", inconvertibleErrorCode()); + bool isGOTSection = isELFGOTSection(Sec); + bool isStubsSection = isELFStubsSection(Sec); + bool SectionContainsContent = false; bool SectionContainsZeroFill = false; @@ -64,7 +111,29 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) { if (Sym->getAddress() > LastSym->getAddress()) LastSym = Sym; - if (Sym->hasName()) { + if (isGOTSection) { + if (Sym->isSymbolZeroFill()) + return make_error("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("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()}; diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp index 18584e5..fc70934 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp @@ -49,12 +49,6 @@ static Expected getMachOGOTTarget(LinkGraph &G, Block &B) { "\" points to anonymous " "symbol", inconvertibleErrorCode()); - if (TargetSym.isDefined() || TargetSym.isAbsolute()) - return make_error( - "GOT entry \"" + TargetSym.getName() + "\" in " + G.getName() + ", \"" + - TargetSym.getBlock().getSection().getName() + - "\" does not point to an external symbol", - inconvertibleErrorCode()); return TargetSym; } -- 2.7.4