[RuntimeDyld][ORC] Add support for Thumb mode to RuntimeDyldMachOARM.

This patch adds support for thumb relocations to RuntimeDyldMachOARM, and adds
a target-specific flags field to JITSymbolFlags (so that on ARM we can record
whether each symbol is Thumb-mode code).

RuntimeDyldImpl::emitSection is modified to ensure that stubs memory is
correctly aligned based on the size returned by getStubAlignment().

llvm-svn: 310517
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index 95b04fd..e046a85 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -149,8 +149,8 @@
   /// The size of this relocation (MachO specific).
   unsigned Size;
 
-  // COFF specific.
-  bool IsTargetThumbFunc;
+  // ARM (MachO and COFF) specific.
+  bool IsTargetThumbFunc = false;
 
   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend)
       : SectionID(id), Offset(offset), RelType(type), Addend(addend),
@@ -195,12 +195,14 @@
   uint64_t Offset;
   int64_t Addend;
   const char *SymbolName;
+  bool IsStubThumb = false;
   RelocationValueRef() : SectionID(0), Offset(0), Addend(0),
                          SymbolName(nullptr) {}
 
   inline bool operator==(const RelocationValueRef &Other) const {
     return SectionID == Other.SectionID && Offset == Other.Offset &&
-           Addend == Other.Addend && SymbolName == Other.SymbolName;
+           Addend == Other.Addend && SymbolName == Other.SymbolName &&
+           IsStubThumb == Other.IsStubThumb;
   }
   inline bool operator<(const RelocationValueRef &Other) const {
     if (SectionID != Other.SectionID)
@@ -209,6 +211,8 @@
       return Offset < Other.Offset;
     if (Addend != Other.Addend)
       return Addend < Other.Addend;
+    if (IsStubThumb != Other.IsStubThumb)
+      return IsStubThumb < Other.IsStubThumb;
     return SymbolName < Other.SymbolName;
   }
 };
@@ -216,21 +220,21 @@
 /// @brief Symbol info for RuntimeDyld.
 class SymbolTableEntry {
 public:
-  SymbolTableEntry()
-      : Offset(0), SectionID(0) {}
+  SymbolTableEntry() = default;
 
   SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags)
       : Offset(Offset), SectionID(SectionID), Flags(Flags) {}
 
   unsigned getSectionID() const { return SectionID; }
   uint64_t getOffset() const { return Offset; }
+  void setOffset(uint64_t NewOffset) { Offset = NewOffset; }
 
   JITSymbolFlags getFlags() const { return Flags; }
 
 private:
-  uint64_t Offset;
-  unsigned SectionID;
-  JITSymbolFlags Flags;
+  uint64_t Offset = 0;
+  unsigned SectionID = 0;
+  JITSymbolFlags Flags = JITSymbolFlags::None;
 };
 
 typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
@@ -365,6 +369,18 @@
   /// Dst.
   void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const;
 
+  /// Generate JITSymbolFlags from a libObject symbol.
+  virtual JITSymbolFlags getJITSymbolFlags(const BasicSymbolRef &Sym);
+
+  /// Modify the given target address based on the given symbol flags.
+  /// This can be used by subclasses to tweak addresses based on symbol flags,
+  /// For example: the MachO/ARM target uses it to set the low bit if the target
+  /// is a thumb symbol.
+  virtual uint64_t modifyAddressBasedOnFlags(uint64_t Addr,
+                                             JITSymbolFlags Flags) const {
+    return Addr;
+  }
+
   /// \brief Given the common symbols discovered in the object file, emit a
   /// new section for them and update the symbol mappings in the object and
   /// symbol table.
@@ -493,6 +509,12 @@
     if (SymEntry.getSectionID() != AbsoluteSymbolSection)
       SectionAddr = getSectionLoadAddress(SymEntry.getSectionID());
     uint64_t TargetAddr = SectionAddr + SymEntry.getOffset();
+
+    // FIXME: Have getSymbol should return the actual address and the client
+    //        modify it based on the flags. This will require clients to be
+    //        aware of the target architecture, which we should build
+    //        infrastructure for.
+    TargetAddr = modifyAddressBasedOnFlags(TargetAddr, SymEntry.getFlags());
     return JITEvaluatedSymbol(TargetAddr, SymEntry.getFlags());
   }