[llvm-jitlink] Add suppport for testing GOT entries and stubs for ELF.
authorLang Hames <lhames@gmail.com>
Fri, 17 Jul 2020 21:56:51 +0000 (14:56 -0700)
committerLang Hames <lhames@gmail.com>
Sat, 18 Jul 2020 00:55:30 +0000 (17:55 -0700)
This enables regression testing of GOT and stub handling with
llvm-jitlink.

llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
llvm/tools/llvm-jitlink/llvm-jitlink-macho.cpp

index 1b74f10..beb73fb 100644 (file)
 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) {
@@ -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<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()};
index 18584e5..fc70934 100644 (file)
@@ -49,12 +49,6 @@ static Expected<Symbol &> getMachOGOTTarget(LinkGraph &G, Block &B) {
             "\" points to anonymous "
             "symbol",
         inconvertibleErrorCode());
-  if (TargetSym.isDefined() || TargetSym.isAbsolute())
-    return make_error<StringError>(
-        "GOT entry \"" + TargetSym.getName() + "\" in " + G.getName() + ", \"" +
-            TargetSym.getBlock().getSection().getName() +
-            "\" does not point to an external symbol",
-        inconvertibleErrorCode());
   return TargetSym;
 }