From: Julian Seward Date: Tue, 17 Oct 2006 01:54:54 +0000 (+0000) Subject: Merge r6153: Add client startup code for AIX5. X-Git-Tag: svn/VALGRIND_3_3_0~591 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f3fc1d2dc45487f12b397f35474d33a0492cb36;p=thirdparty%2Fvalgrind.git Merge r6153: Add client startup code for AIX5. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6285 --- diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S index 59f8588bf8..803e34d10e 100644 --- a/coregrind/m_trampoline.S +++ b/coregrind/m_trampoline.S @@ -29,7 +29,13 @@ */ #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 ---*/ /*--------------------------------------------------------------------*/ diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h index 99b3e2050d..11080713c8 100644 --- a/coregrind/pub_core_trampoline.h +++ b/coregrind/pub_core_trampoline.h @@ -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