[LLVMdev] X86 32bit Patch Point Support

lin zuojian manjian2006 at gmail.com
Thu Jun 18 22:58:07 PDT 2015


Hi,
    I am tring to build an arm translator based on qemu and LLVM. JIT
    code is targeted as 32bit machine.
    And multiple error from LLVM has occured, so I fix them. See the
    patch.
    One tricky that I have not fix but workaround it, as follow:
Index: lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
===================================================================
--- lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp	(revision 239983)
+++ lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp	(working copy)
@@ -167,7 +167,6 @@
 static X86_32RelType getType32(X86_64RelType T) {
   switch (T) {
   case RT64_64:
-    llvm_unreachable("Unimplemented");
   case RT64_32:
   case RT64_32S:
     return RT32_32;

     I know it is wrong to do so. But I also know the patch
     point function only take the first parameter as a dummy one. So I
     work it around.

Here is the arm code:
00000000 <test>:
   0:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
   4:	e28db000 	add	fp, sp, #0
   8:	e1a00000 	nop			; (mov r0, r0)
   c:	e24bd000 	sub	sp, fp, #0
  10:	e49db004 	pop	{fp}		; (ldr fp, [sp], #4)
  14:	e12fff1e 	bx	lr

Here is the llvm ir:
; ModuleID = 'test'

define fastcc void @main([649 x i32]*) {
Prologue:
  %1 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 0
  %2 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 0
  %3 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 1
  %4 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 2
  %5 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 3
  %6 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 4
  %7 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 5
  %8 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 6
  %9 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 7
  %10 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 8
  %11 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 9
  %12 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 10
  %13 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 11
  %14 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 12
  %15 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 13
  %16 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 14
  %17 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 15
  %18 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 128
  %19 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 130
  %20 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 129
  %21 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 131
  %22 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 553
  %23 = bitcast i32* %22 to i64*
  %24 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 555
  %25 = bitcast i32* %24 to i64*
  %26 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 559
  %27 = bitcast i32* %26 to i64*
  %28 = getelementptr [649 x i32], [649 x i32]* %0, i32 0, i32 561
  %29 = load i32, i32* %15
  %30 = add i32 %29, -4
  store i32 %30, i32* %15
  %31 = load i32, i32* %15
  %32 = inttoptr i32 %31 to i32*
  %33 = load i32, i32* %13
  store i32 %33, i32* %32
  %34 = load i32, i32* %15
  %35 = add i32 %34, 0
  store i32 %35, i32* %15
  %36 = load i32, i32* %15
  %37 = sub i32 %36, 0
  store i32 %37, i32* %15
  %38 = load i32, i32* %15
  %39 = inttoptr i32 %38 to i32*
  %40 = load i32, i32* %39
  %41 = load i32, i32* %15
  %42 = add i32 %41, 4
  store i32 %42, i32* %15
  %43 = load i32, i32* %16
  %44 = and i32 %43, -2
  store i32 %44, i32* %17
  %45 = load i32, i32* %16
  %46 = and i32 %45, 1
  store i32 %46, i32* %16
  %47 = bitcast i32* %1 to i8*
  %48 = getelementptr i8, i8* %47, i32 536
  %49 = bitcast i8* %48 to i32*
  %50 = load i32, i32* %16
  store i32 %50, i32* %49
  call anyregcc void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 1, i32 10, i8* null, i32 0)
  unreachable
}

declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)

Here is what finally done:

   0xf7fd3000:	mov    %ebp,%ecx
   0xf7fd3002:	push   %ebp
   0xf7fd3003:	mov    %esp,%ebp
   0xf7fd3005:	sub    $0x8,%esp
   0xf7fd3008:	mov    0x34(%ecx),%eax
   0xf7fd300b:	lea    -0x4(%eax),%edx
   0xf7fd300e:	mov    %edx,0x34(%ecx)
   0xf7fd3011:	mov    0x2c(%ecx),%edx
   0xf7fd3014:	mov    %edx,-0x4(%eax)
   0xf7fd3017:	addl   $0x4,0x34(%ecx)
   0xf7fd301b:	mov    0x38(%ecx),%eax
   0xf7fd301e:	mov    %eax,%edx
   0xf7fd3020:	and    $0xfffffffe,%edx
   0xf7fd3023:	mov    %edx,0x3c(%ecx)
   0xf7fd3026:	and    $0x1,%eax
   0xf7fd3029:	mov    %eax,0x38(%ecx)
   0xf7fd302c:	mov    %eax,0x218(%ecx)
   0xf7fd3032:	mov    %ebp,%esp
   0xf7fd3034:	pop    %ebp
   0xf7fd3035:	mov    $0x80545cc,%eax
   0xf7fd303a:	jmp    *%eax

The patch is in the attachment.
For anyone feel interested in my code, here's my source:
https://github.com/linzj/arm_translator

I use chromium's gyp + ninja to build, so you need to download deptool
here:
git clone
https://chromium.googlesource.com/chromium/tools/depot_tools.git
export to your PATH, and invoke ./my_gyp
ensure your PATH contains a arm-linux-android-eabi- toolchain
and call ./out/Debug/testQEMU tests/test1.txt
--
Lin Zuojian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 1.patch
Type: text/x-diff
Size: 4194 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150619/8bfe46f7/attachment.patch>


More information about the llvm-dev mailing list