]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r6153: Add client startup code for AIX5.
authorJulian Seward <jseward@acm.org>
Tue, 17 Oct 2006 01:54:54 +0000 (01:54 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 17 Oct 2006 01:54:54 +0000 (01:54 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6285

coregrind/m_trampoline.S
coregrind/pub_core_trampoline.h

index 59f8588bf823b30045430105dfa9eddb2e3aaed1..803e34d10e4570a9c55283f227e9640b372c3727 100644 (file)
 */
 
 #include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+
+/* We need pub_core_vkiscnums.h, but the AIX5 formulation
+   brings in a load of C declarations.  Defining this macro
+   makes them invisible.  Yes, a nasty hack. */
+#define VG_IN_ASSEMBLY_SOURCE
+#  include "pub_core_vkiscnums.h"
+#undef VG_IN_ASSEMBLY_SOURCE
 
 /* ------------------ SIMULATED CPU HELPERS ------------------ */
 /* 
@@ -299,8 +305,8 @@ VG_(trampoline_stuff_end):
 VG_(trampoline_stuff_start):
 
        /* See comment in pub_core_trampoline.h for what this is for */
-.global VG_(ppc64_linux_magic_redirect_return_stub)
-VG_(ppc64_linux_magic_redirect_return_stub):
+.global VG_(ppctoc_magic_redirect_return_stub)
+VG_(ppctoc_magic_redirect_return_stub):
        trap
 
        /* this function is written using the "dotless" ABI convention */
@@ -377,6 +383,279 @@ VG_(trampoline_stuff_end):
 #      undef UD2_1024
 #      undef UD2_PAGE
 
+/*---------------- ppc32-aix5 ----------------*/
+#else
+#if defined(VGP_ppc32_aix5)
+
+#      define UD2_16     trap ; trap ; trap; trap
+#      define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
+#      define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
+#      define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
+#      define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
+
+       .csect .text[PR]
+
+       /* a leading page of unexecutable code */
+       UD2_PAGE
+
+.globl VG_(trampoline_stuff_start)
+VG_(trampoline_stuff_start):
+
+/* See pub_core_trampoline.h for an explaination of this.  Also
+   see pub_core_initimg.h, struct AIX5PreloadPage.  On entry, r3
+   points to an AIX5PreloadPage structure.  Note we can only 
+   use r2-r10 as scratch registers here since those are the
+   only ones restored from the preload page when finally
+   starting the client. */
+.globl VG_(ppc32_aix5_do_preloads_then_start_client)
+VG_(ppc32_aix5_do_preloads_then_start_client):
+       stwu    1,-1024(1)
+       stw     3,512(1)        /* stash r3 512 bytes up stack */
+
+       /* Try to load .../vgpreload_core.so */
+       lwz     2,0(3)          /* r2 = __NR___loadx */
+       lwz     5,20(3)         /* r5 = off_preloadcorename */
+       add     6,3,5           /* r6 = preloadcorename */
+       bl      do___loadx
+       cmpwi   0,3,0
+       beq     .Lfailed
+
+       /* Try to load .../vgpreload_tool.so, if it exists */
+       lwz     3,512(1)        /* restore r3 */
+       lwz     2,0(3)          /* r2 = __NR___loadx */
+       lwz     5,24(3)         /* r5 = off_preloadtoolname */
+       cmpwi   0,5,0           /* skip tool preload if */
+       beq     .Ltry_preload   /* name not present */
+       add     6,3,5           /* r6 = preloadtoolname */
+       bl      do___loadx
+       cmpwi   0,3,0
+       beq     .Lfailed
+
+.Ltry_preload:
+       /* Try to load the LD_PRELOAD= file, if it exists */
+       lwz     3,512(1)        /* restore r3 */
+       lwz     2,0(3)          /* r2 = __NR___loadx */
+       lwz     5,28(3)         /* r5 = off_ld_preloadname */
+       cmpwi   0,5,0           /* skip ld_preload if */
+       beq     .Lstart_client  /* name not present */
+       add     6,3,5           /* r6 = ld_preloadname */
+       bl      do___loadx
+       cmpwi   0,3,0
+       beq     .Lfailed
+       
+.Lstart_client:
+       /* Success.  Restore r2-r10 from preloadpage-> and start
+       the client. */
+       lwz     3,512(1)        /* restore r3 */
+       addi    1,1,1024
+       lwz     2,32+4(3)       /* preloadpage->client_start */
+       mtctr   2
+       lwz     2,40+4(3)       /* preloadpage->r2 */
+       lwz     4,56+4(3)       /* preloadpage->r4 */
+       lwz     5,64+4(3)       /* preloadpage->r5 */
+       lwz     6,72+4(3)       /* preloadpage->r6 */
+       lwz     7,80+4(3)       /* preloadpage->r7 */
+       lwz     8,88+4(3)       /* preloadpage->r8 */
+       lwz     9,96+4(3)       /* preloadpage->r9 */
+       lwz     10,104+4(3)     /* preloadpage->r10 */
+       lwz     3,48+4(3)       /* preloadpage->r3 */
+       bctr
+       /*NOTREACHED*/
+       trap
+
+.Lfailed:
+       /* __loadx barfed for some reason.  Print the error
+       message and get out. */
+       /* First the error msg */
+       lwz     3,512(1)        /* restore r3 */
+       lwz     2,4(3)          /* r2 = __NR_kwrite */
+       lwz     4,12(3)         /* r4 = offset of err msg */
+       add     4,4,3           /* r4 = err msg */
+       lwz     5,16(3)         /* r5 = length err msg */
+       li      3,2             /* r3 = stderr */
+       bl      do_syscall
+       /* now call the diagnosis fn */
+       lwz     3,512(1)        /* restore r3 */
+       lwz     4,112(3)        /* preloadpage->p_diagnose_load_failure */
+       lwz     2,4(4)          /* get its TOC ptr */
+       lwz     4,0(4)          /* get its entry point */
+       mtlr    4
+       blrl
+       /* Now do _exit(1) */
+       lwz     3,512(1)        /* restore r3 */
+       lwz     2,8(3)          /* r2 = __NR_exit */
+       li      3,1             /* doing _exit(1) */
+       addi    1,1,1024        /* fix stack pointer */
+       bl      do_syscall
+       /*NOTREACHED*/
+       trap
+       
+do___loadx:
+       /* On entry: r2 = __NR___loadx, r6 = name of module */
+       li      3,1
+       slwi    3,3,24  /* r3 = 0x1000000 = VKI_DL_LOAD */
+       li      4,0
+       li      5,0
+       li      7,0
+       li      8,0
+       li      9,0
+       li      10,0
+do_syscall:
+       sc
+       /* sc continues at 'lr', hence this 
+       constitutes an automatic return */
+
+
+       /* See comment in pub_core_trampoline.h for what this is for */
+.globl VG_(ppctoc_magic_redirect_return_stub)
+VG_(ppctoc_magic_redirect_return_stub):
+       trap
+       
+.globl VG_(trampoline_stuff_end)
+VG_(trampoline_stuff_end):
+
+       /* and a trailing page of unexecutable code */
+       UD2_PAGE
+
+#      undef UD2_16
+#      undef UD2_64
+#      undef UD2_256
+#      undef UD2_1024
+#      undef UD2_PAGE
+
+/*---------------- ppc64-aix5 ----------------*/
+#else
+#if defined(VGP_ppc64_aix5)
+
+#      define UD2_16     trap ; trap ; trap; trap
+#      define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
+#      define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
+#      define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
+#      define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
+
+.globl VG_(trampoline_stuff_start)
+VG_(trampoline_stuff_start):
+/* See pub_core_trampoline.h for an explaination of this.  Also
+   see pub_core_initimg.h, struct AIX5PreloadPage.  On entry, r3
+   points to an AIX5PreloadPage structure.  Note we can only 
+   use r2-r10 as scratch registers here since those are the
+   only ones restored from the preload page when finally
+   starting the client. */
+.globl VG_(ppc64_aix5_do_preloads_then_start_client)
+VG_(ppc64_aix5_do_preloads_then_start_client):
+       stdu    1,-1024(1)
+       std     3,512(1)        /* stash r3 512 bytes up stack */
+
+       /* Try to load .../vgpreload_core.so */
+       lwz     2,0(3)          /* r2 = __NR_kload */
+       lwz     5,20(3)         /* r5 = off_preloadcorename */
+       add     3,3,5           /* r6 = preloadcorename */
+       bl      do_kload
+       cmpdi   0,3,0
+       beq     .Lfailed
+
+       /* Try to load .../vgpreload_tool.so, if it exists */
+       ld      3,512(1)        /* restore r3 */
+       lwz     2,0(3)          /* r2 = __NR_kload */
+       lwz     5,24(3)         /* r5 = off_preloadtoolname */
+       cmpwi   0,5,0           /* skip tool preload if */
+       beq     .Ltry_preload   /* name not present */
+       add     3,3,5           /* r6 = preloadtoolname */
+       bl      do_kload
+       cmpdi   0,3,0
+       beq     .Lfailed
+
+.Ltry_preload:
+       /* Try to load the LD_PRELOAD= file, if it exists */
+       ld      3,512(1)        /* restore r3 */
+       lwz     2,0(3)          /* r2 = __NR_kload */
+       lwz     5,28(3)         /* r5 = off_ld_preloadname */
+       cmpwi   0,5,0           /* skip ld_preload if */
+       beq     .Lstart_client  /* name not present */
+       add     3,3,5           /* r6 = ld_preloadname */
+       bl      do_kload
+       cmpdi   0,3,0
+       beq     .Lfailed
+       
+.Lstart_client:
+       /* Success.  Restore r2-r10 from preloadpage-> and start
+       the client. */
+       ld      3,512(1)        /* restore r3 */
+       addi    1,1,1024
+       ld      2,32+0(3)       /* preloadpage->client_start */
+       mtctr   2
+       ld      2,40+0(3)       /* preloadpage->r2 */
+       ld      4,56+0(3)       /* preloadpage->r4 */
+       ld      5,64+0(3)       /* preloadpage->r5 */
+       ld      6,72+0(3)       /* preloadpage->r6 */
+       ld      7,80+0(3)       /* preloadpage->r7 */
+       ld      8,88+0(3)       /* preloadpage->r8 */
+       ld      9,96+0(3)       /* preloadpage->r9 */
+       ld      10,104+0(3)     /* preloadpage->r10 */
+       ld      3,48+0(3)       /* preloadpage->r3 */
+       bctr
+       /*NOTREACHED*/
+       trap
+
+.Lfailed:
+       /* __loadx barfed for some reason.  Print the error
+       message and get out. */
+       /* First the error msg */
+       ld      3,512(1)        /* restore r3 */
+       lwz     2,4(3)          /* r2 = __NR_kwrite */
+       lwz     4,12(3)         /* r4 = offset of err msg */
+       add     4,4,3           /* r4 = err msg */
+       lwz     5,16(3)         /* r5 = length err msg */
+       li      3,2             /* r3 = stderr */
+       bl      do_syscall
+       /* now call the diagnosis fn */
+       ld      3,512(1)        /* restore r3 */
+       ld      4,112(3)        /* preloadpage->p_diagnose_load_failure */
+       ld      11,16(4)
+       ld      2,8(4)          /* get its TOC ptr */
+       ld      4,0(4)          /* get its entry point */
+       mtlr    4
+       blrl
+       /* Now do _exit(1) */
+       lwz     3,512(1)        /* restore r3 */
+       lwz     2,8(3)          /* r2 = __NR_exit */
+       li      3,1             /* doing _exit(1) */
+       addi    1,1,1024        /* fix stack pointer */
+       bl      do_syscall
+       /*NOTREACHED*/
+       trap
+       
+do_kload:
+       /* On entry: r2 = __NR_kload,   r3 = name of module */
+       li      4,0
+       li      5,0
+       li      6,0
+       li      7,0
+       li      8,0
+       li      9,0
+       li      10,0
+do_syscall:
+       sc
+       /* sc continues at 'lr', hence this 
+       constitutes an automatic return */
+
+       /* See comment in pub_core_trampoline.h for what this is for */
+.globl VG_(ppctoc_magic_redirect_return_stub)
+VG_(ppctoc_magic_redirect_return_stub):
+       trap
+       
+.globl VG_(trampoline_stuff_end)
+VG_(trampoline_stuff_end):
+
+       /* and a trailing page of unexecutable code */
+       UD2_PAGE
+
+#      undef UD2_16
+#      undef UD2_64
+#      undef UD2_256
+#      undef UD2_1024
+#      undef UD2_PAGE
+       
 /*---------------- unknown ----------------*/
 #else
 #  error Unknown platform
@@ -385,11 +664,14 @@ VG_(trampoline_stuff_end):
 #endif
 #endif
 #endif
+#endif
+#endif
 
-
+#if defined(VGO_linux)
 /* Let the linker know we don't need an executable stack */
 .section .note.GNU-stack,"",@progbits
-               
+#endif
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 99b3e2050deeb2b723892fe431a7b0566cce5bab..11080713c8e55cf6da31aedfe8ec382ea84b9cfc 100644 (file)
@@ -79,12 +79,34 @@ extern UInt  VG_(ppc64_linux_REDIR_FOR_strlen)( void* );
 extern void* VG_(ppc64_linux_REDIR_FOR_strchr)( void*, Int );
 /* A label (sans dot) marking the ultra-magical return stub via which
    all redirected and wrapped functions are made to "return" on
-   ppc64-linux.  The one insn at this label is never really
-   translated.  Instead, m_translate generates IR to restore the
-   thread's LR and R2 registers from a small stack in the ppc64 guest
-   state structure, and then branch to LR.  Convoluted?  Confusing?
-   You betcha.  Could I think of anything simpler?  No. */
-extern void VG_(ppc64_linux_magic_redirect_return_stub);
+   ppc64-linux/ppc64-aix5/ppc32-aix5.  The one insn at this label is
+   never really translated.  Instead, m_translate generates IR to
+   restore the thread's LR and R2 registers from a small stack in the
+   ppc64 guest state structure, and then branch to LR.  Convoluted?
+   Confusing?  You betcha.  Could I think of anything simpler?  No. */
+extern void VG_(ppctoc_magic_redirect_return_stub);
+#endif
+
+#if defined(VGP_ppc32_aix5)
+/* A label (sans dot) marking the client start point for ppc32_aix5.
+   This function is entered with r3 holding a pointer to the
+   AIX5PreloadPage struct set up by m_initimg.  It first tries to
+   __loadx the _core.so and _tool.so preloads mentioned in the struct;
+   then it cleans up the register state to be more what it really
+   should be at client startup, and finally it jumps to the client's
+   real entry point. */
+extern void VG_(ppc32_aix5_do_preloads_then_start_client);
+
+/* See comment for VG_(ppctoc_magic_redirect_return_stub) above. */
+extern void VG_(ppctoc_magic_redirect_return_stub);
+#endif
+
+#if defined(VGP_ppc64_aix5)
+/* See comment for VG_(ppctoc_magic_redirect_return_stub) above. */
+extern void VG_(ppctoc_magic_redirect_return_stub);
+
+/* See comment for ppc32_aix5 equivalent above. */
+extern void VG_(ppc64_aix5_do_preloads_then_start_client);
 #endif
  
 #endif   // __PUB_CORE_TRAMPOLINE_H