aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
diff options
context:
space:
mode:
authorStefan Gränitz <stefan.graenitz@gmail.com>2024-01-23 02:59:30 +0100
committerGitHub <noreply@github.com>2024-01-23 02:59:30 +0100
commite5ca202ef8870f3b46cc19a7a62624e6908be9a8 (patch)
tree18e3549fbe72be58917ad63b7be0d68b9ac390dd /llvm/tools/llvm-jitlink/llvm-jitlink.cpp
parentb8e708b9d39862c2b7595c02e7bdc4878a2d7186 (diff)
downloadllvm-e5ca202ef8870f3b46cc19a7a62624e6908be9a8.zip
llvm-e5ca202ef8870f3b46cc19a7a62624e6908be9a8.tar.gz
llvm-e5ca202ef8870f3b46cc19a7a62624e6908be9a8.tar.bz2
[JITLink][AArch32] Multi-stub support for armv7/thumbv7 (#78371)
We want to emit stubs that match the instruction set state of the relocation site. This is important for branches that have no built-in switch for the instruction set state. It's the case for Jump24 relocations. Relocations on instructions that support switching on the fly will be rewritten in a relaxation step in the future. This affects Call relocations on `BL`/`BLX` instructions. In this patch, the StubManager gains a second stub symbol slot for each target and selects which one to use based on the relocation type. For testing, we select the appropriate slot with a stub-kind filter, i.e. `arm` or `thumb`. With that we can implement Armv7 stubs and test that we can have both kinds of stubs for a single external symbol.
Diffstat (limited to 'llvm/tools/llvm-jitlink/llvm-jitlink.cpp')
-rw-r--r--llvm/tools/llvm-jitlink/llvm-jitlink.cpp46
1 files changed, 45 insertions, 1 deletions
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 7e21377..b2a1338 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -1265,8 +1265,52 @@ Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
return SecInfoItr->second;
}
+class MemoryMatcher {
+public:
+ MemoryMatcher(ArrayRef<char> Content)
+ : Pos(Content.data()), End(Pos + Content.size()) {}
+
+ template <typename MaskType> bool matchMask(MaskType Mask) {
+ if (Mask == (Mask & *reinterpret_cast<const MaskType *>(Pos))) {
+ Pos += sizeof(MaskType);
+ return true;
+ }
+ return false;
+ }
+
+ template <typename ValueType> bool matchEqual(ValueType Value) {
+ if (Value == *reinterpret_cast<const ValueType *>(Pos)) {
+ Pos += sizeof(ValueType);
+ return true;
+ }
+ return false;
+ }
+
+ bool done() const { return Pos == End; }
+
+private:
+ const char *Pos;
+ const char *End;
+};
+
static StringRef detectStubKind(const Session::MemoryRegionInfo &Stub) {
- // Implement acutal stub kind detection
+ constexpr uint32_t Armv7MovWTle = 0xe300c000;
+ constexpr uint32_t Armv7BxR12le = 0xe12fff1c;
+ constexpr uint32_t Thumbv7MovWTle = 0x0c00f240;
+ constexpr uint16_t Thumbv7BxR12le = 0x4760;
+
+ MemoryMatcher M(Stub.getContent());
+ if (M.matchMask(Thumbv7MovWTle)) {
+ if (M.matchMask(Thumbv7MovWTle))
+ if (M.matchEqual(Thumbv7BxR12le))
+ if (M.done())
+ return "thumbv7_abs_le";
+ } else if (M.matchMask(Armv7MovWTle)) {
+ if (M.matchMask(Armv7MovWTle))
+ if (M.matchEqual(Armv7BxR12le))
+ if (M.done())
+ return "armv7_abs_le";
+ }
return "";
}