[RuntimeDyld] Improve error diagnostic in RuntimeDyldChecker.
authorLang Hames <lhames@gmail.com>
Thu, 10 Jul 2014 23:26:20 +0000 (23:26 +0000)
committerLang Hames <lhames@gmail.com>
Thu, 10 Jul 2014 23:26:20 +0000 (23:26 +0000)
The compiler often emits assembler-local labels (beginning with 'L') for use in
relocation expressions, however these aren't included in the object files.
Teach RuntimeDyldChecker to warn the user if they try to use one of these in an
expression, since it will never work.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212777 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/RuntimeDyldChecker.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp

index 38a4ea1ad5229ee157513c444cf128b3f6b70615..8dd891e8364829f33d823b44503995ee69a4ed13 100644 (file)
@@ -81,7 +81,7 @@ public:
 
 private:
 
-  bool checkSymbolIsValidForLoad(StringRef Symbol) const;
+  bool isSymbolValid(StringRef Symbol) const;
   uint64_t getSymbolAddress(StringRef Symbol) const;
   uint64_t readMemoryAtSymbol(StringRef Symbol, int64_t Offset,
                               unsigned Size) const;
index 190bbbf93ff8b222d17d7525eef037e0d6b203d0..b10ec360aa516a30adccd61ef29d1f8e6d713e0f 100644 (file)
@@ -199,7 +199,7 @@ namespace llvm {
       StringRef Symbol;
       std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
 
-      if (!Checker.checkSymbolIsValidForLoad(Symbol))
+      if (!Checker.isSymbolValid(Symbol))
         return std::make_pair(EvalResult(("Cannot decode unknown symbol '" +
                                           Symbol + "'").str()),
                               "");
@@ -268,7 +268,7 @@ namespace llvm {
       StringRef Symbol;
       std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
 
-      if (!Checker.checkSymbolIsValidForLoad(Symbol))
+      if (!Checker.isSymbolValid(Symbol))
         return std::make_pair(EvalResult(("Cannot decode unknown symbol '"
                                           + Symbol + "'").str()),
                               "");
@@ -304,6 +304,17 @@ namespace llvm {
       else if (Symbol == "next_pc")
         return evalNextPC(RemainingExpr);
 
+      if (!Checker.isSymbolValid(Symbol)) {
+        std::string ErrMsg("No known address for symbol '");
+        ErrMsg += Symbol;
+        ErrMsg += "'";
+        if (Symbol.startswith("L"))
+          ErrMsg += " (this appears to be an assembler local label - "
+                    " perhaps drop the 'L'?)";
+
+        return std::make_pair(EvalResult(ErrMsg), "");
+      }
+
       // Looks like a plain symbol reference.
       return std::make_pair(EvalResult(Checker.getSymbolAddress(Symbol)),
                             RemainingExpr);
@@ -397,7 +408,7 @@ namespace llvm {
       StringRef Symbol;
       std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
 
-      if (!Checker.checkSymbolIsValidForLoad(Symbol))
+      if (!Checker.isSymbolValid(Symbol))
         return std::make_pair(EvalResult(("Cannot dereference unknown symbol '"
                                           + Symbol + "'").str()),
                               "");
@@ -612,7 +623,7 @@ bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
   return DidAllTestsPass && (NumRules != 0);
 }
 
-bool RuntimeDyldChecker::checkSymbolIsValidForLoad(StringRef Symbol) const {
+bool RuntimeDyldChecker::isSymbolValid(StringRef Symbol) const {
   return RTDyld.getSymbolAddress(Symbol) != nullptr;
 }