From 565ebde5fea42789c7df8a49ce1e270d49d525a1 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 3 Oct 2012 16:29:42 +0000 Subject: [PATCH] Implement .rel relocation for R_ARM_ABS32 in MCJIT. Patch by Amara Emerson. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165128 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 12 ++++++++++-- test/ExecutionEngine/MCJIT/test-ptr-reloc.ll | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 test/ExecutionEngine/MCJIT/test-ptr-reloc.ll diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 597c5cb131f..efefacf632d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -264,14 +264,19 @@ void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress, default: llvm_unreachable("Not implemented relocation type!"); - // Just write 32bit value to relocation address + // Write a 32bit value to relocation address, taking into account the + // implicit addend encoded in the target. case ELF::R_ARM_ABS32 : - *TargetPtr = Value; + *TargetPtr += Value; break; // Write first 16 bit of 32 bit value to the mov instruction. // Last 4 bit should be shifted. case ELF::R_ARM_MOVW_ABS_NC : + // We are not expecting any other addend in the relocation address. + // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 + // non-contiguous fields. + assert((*TargetPtr & 0x000F0FFF) == 0); Value = Value & 0xFFFF; *TargetPtr |= Value & 0xFFF; *TargetPtr |= ((Value >> 12) & 0xF) << 16; @@ -280,6 +285,9 @@ void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress, // Write last 16 bit of 32 bit value to the mov instruction. // Last 4 bit should be shifted. case ELF::R_ARM_MOVT_ABS : + // We are not expecting any other addend in the relocation address. + // Use 0x000F0FFF for the same reason as R_ARM_MOVW_ABS_NC. + assert((*TargetPtr & 0x000F0FFF) == 0); Value = (Value >> 16) & 0xFFFF; *TargetPtr |= Value & 0xFFF; *TargetPtr |= ((Value >> 12) & 0xF) << 16; diff --git a/test/ExecutionEngine/MCJIT/test-ptr-reloc.ll b/test/ExecutionEngine/MCJIT/test-ptr-reloc.ll new file mode 100644 index 00000000000..93b6a6deffd --- /dev/null +++ b/test/ExecutionEngine/MCJIT/test-ptr-reloc.ll @@ -0,0 +1,16 @@ +; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -O0 %s + +@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 +@ptr = global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), align 4 +@.str1 = private unnamed_addr constant [6 x i8] c"data2\00", align 1 +@ptr2 = global i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), align 4 + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readonly { +entry: + %0 = load i8** @ptr, align 4 + %1 = load i8** @ptr2, align 4 + %cmp = icmp eq i8* %0, %1 + %. = zext i1 %cmp to i32 + ret i32 %. +} + -- 2.11.0